 Recursive Tree creator for Unity3D

a guest
Mar 31st, 2014
1,550
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. /// Let's draw trees with a recursive algorithm in Unity!
2. /// 2014 Aaron San Filippo (@AeornFlippout)
3. /// Let me know if you have fun with this or make any cool additions :)
4.
5. //INSTRUCTIONS:
6. //1. attach this component to an object in your scene that the camera can see.
7. // (see further instructions below)
8.
9.
10. using UnityEngine;
11. using System.Collections;
12. using System.Collections.Generic;
13.
14. [System.Serializable]
15. public class TreeParms
16. {
17.
18. public float branchAngle = 15.0f; //how far left/right each branch goes from its parent.
19. public float minScale = 0.05f; //what's the minimum scale of each branch?
20. public float scaleChange = 0.05f; //how much smaller than its parent is each branch?
21. public float angleRandom = 5.0f; //how much random variation is there in the angle for each branch?
22. public float scaleRandom = 0.1f; // how much random variation is there in the scale for each branch?
23.
24. public int maxDepth = 15; //what's the maximum "depth" of the recursive algorithm?
25.
26. }
27.
28. public class Tree : MonoBehaviour {
29.
30.
31. //2. point this at a prefab that's a skinny quad or something with height of 1 unit, where the origin is at the base.
32. //for instance - make an 'empty' object with a child 'quad' offset by .5 units in the Y direction.
33. public GameObject trunkPrefab;
34.
35.
36. public Vector3 trunkTopOffset = new Vector3(0, 1, 0);
37.
38. // 3. Play around with these parameters.
39. //Note: careful with "scaleChange" and especially "max depth" - it can make the algorithm take a VERY long time.
40. public TreeParms parms;
41.
42. //4. push this checkbox to re-calculate in the Unity editor at runtime.
43. public bool reCalulateNow = false;
44.
45. Transform root;
46. List<GameObject> trunks = new List<GameObject>(1000000);
47.
48. // Use this for initialization
49. void Start () {
50. root = transform;
51. MakeTree(root.position, 0, 1.0f, 0);
52. }
53.
54.
55. void Update () {
56. if(reCalulateNow)
57. {
58. reCalulateNow = false;
59. for(int i=0;i<trunks.Count; i++)
60. {
61. GameObject.Destroy( trunks[i]);
62. }
63.
64. MakeTree(root.position, 0, 1.0f, 0);
65.
66. }
67. }
68.
69.
70. void MakeTree(Vector3 startPos, float angle, float scale, int depth)
71. {
72. //create a quaternion specified with euler angles where we rotate around 'x'
73. Quaternion rot = Quaternion.Euler( 0, 0,angle);// * Quaternion.AngleAxis( Random.Range(0,360), Vector3.up);
74.
75. //make a trunk
76. GameObject obj = (GameObject)GameObject.Instantiate(trunkPrefab, startPos, rot);
77. obj.transform.localScale = new Vector3(scale,scale,scale);
78.
80.
81. //are we at the minimum scale?
82. if(scale < parms.minScale || depth >= parms.maxDepth)
83. return; //done with this 'leaf'!
84.
85.
86. Vector3 topPos = startPos + (rot * (trunkTopOffset * scale));
87.
88. //make a left branch
89. MakeTree( topPos,
90. angle - parms.branchAngle + Random.Range(-parms.angleRandom, parms.angleRandom) ,
91. scale - (parms.scaleChange + Random.Range(0, parms.scaleRandom)),
92. depth+1);
93.
94. //make a right branch
95. MakeTree( topPos,
96. angle + parms.branchAngle+ Random.Range(-parms.angleRandom, parms.angleRandom),
97. scale - (parms.scaleChange + Random.Range(0, parms.scaleRandom) ),
98. depth+1);
99. }
100. }
RAW Paste Data