Guest User

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.  
  79. trunks.Add(obj);
  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