Guest User

treecolider

a guest
May 31st, 2014
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //  SOURCE : Loren Logic
  2. //  http://answers.unity3d.com/questions/282910/tree-collision.html#answer-406989
  3.  
  4. /*
  5. Tree Collision?
  6.  
  7. This is a frequently asked question. The most popular answer is some derivative of the reference manual's topic, "Setting Up Tree Collisions."
  8. That works just fine, and potentially gives every tree its own collider.
  9.  
  10. My cheapo computer has a cheapo video card in it, and I keep it that way so I am forced to optimize my games for those who also have lousy video cards.
  11. It occurred to me that my FPS game's flying protagonist can really only hit the nearest tree, so giving every tree a collider means physics processing for every tree but one has no return on investment.
  12. Why not move one efficient capsule collider to the nearest tree in case I smack into it?
  13. A built-in array and a little math in a short script sped up my FPS dramatically compared to painting trees on my terrain with one probably unused capsule collider each.
  14. I got rid of the capsule collider in my prototype tree and supplied the original colliderless tree to the terrain tool for painting onto my terrain.
  15. I attached the following script "sctTerrain" to the terrain object named "Terrain."
  16. I added a capsule object to the scene having a capsule collider and a kinematic rigidbody (recommended by Unity if I am going to move my collider around a lot).
  17. I sized the capsule by hand to appropriately match the prototype tree, the top branches of which I can fly through without dying.
  18. The capsule has its mesh renderer turned off so it is invisible but still solid. I named the capsule "Tree" so if I fly into the capsule I can report, "Tree got you."
  19. If my script can't find any trees AND cannot find the capsule object, it destroys itself at Start() because it is unneeded.
  20. Otherwise it places the capsule to surround the nearest tree trunk and scales it to match the tree's height less the sparse top branches.
  21. This math-based technique for colliding with trees is fast, and I recommend it:
  22. */
  23.  
  24. // ****
  25. //  TO SETUP :
  26. //  add a capsule object to the scene having a capsule collider and a kinematic rigidbody, named "Tree"
  27. //  attach the following script to the terrain object named "Terrain"
  28. //  drag and drop your Player object in the Inspector
  29. // ****
  30.  
  31.  
  32. #pragma strict
  33.  
  34. public var player : Transform;
  35.  
  36. private var paryTrees : TreeInstance[];
  37. private var pvecTerrainPosition : Vector3;
  38. private var pvecTerrainSize : Vector3;
  39. private var pgobTreeCollide : GameObject;
  40. private var pvecCollideScale : Vector3;
  41. private var pbooCollideWithTrees : boolean = false;
  42.  
  43. function Start()
  44. {
  45.     // Get the terrain's position
  46.     pvecTerrainPosition = Terrain.activeTerrain.transform.position;
  47.  
  48.     // Get the terrain's size from the terrain data
  49.     pvecTerrainSize = Terrain.activeTerrain.terrainData.size;
  50.     // Get the tree instances
  51.     paryTrees = Terrain.activeTerrain.terrainData.treeInstances;
  52.  
  53.     // Get the invisible capsule having the capsule collider that makes the nearest tree solid
  54.     pgobTreeCollide = GameObject.Find("Tree"); // This is a capsule having a capsule collider, but when the flier hits it we want it to be reported that the flier hit a tree.
  55.  
  56.     // Are there trees and a tree collider?
  57.     if ((pgobTreeCollide != null) && (paryTrees.length > 0))
  58.     {
  59.        // Set a flag to make this script useful
  60.        pbooCollideWithTrees = true;
  61.        // Get the original local scale of the capsule. This is manually matched to the scale of the prototype of the tree.
  62.        pvecCollideScale = pgobTreeCollide.transform.localScale;
  63.     }
  64.     // No need to use this script
  65.     else
  66.     {
  67.        Debug.LogWarning( "NO CAPSULE NAMED TREE FOUND, OR NO TERRAIN TREES, DESTROYING SCRIPT..." );
  68.        Destroy(this);
  69.     }
  70.  
  71.     // has the player been assigned in the Inspector?
  72.     if ( !player )
  73.     {
  74.        Debug.LogWarning( "NO PLAYER OBJECT IN THE INSPECTOR, DESTROYING SCRIPT..." );
  75.        Destroy(this);
  76.     }
  77. }
  78.  
  79. function Update()
  80. {
  81.     var L : int;
  82.     var triTree : TreeInstance;
  83.  
  84.     //var vecFlier : Vector3 = sctFly.svecXYZ; // My protagonist's position, passed by a static variable in a script called sctFly.
  85.     var vecFlier : Vector3 = player.position; // using the player transform, dropped in the inspector
  86.  
  87.     var fltProximity : float;
  88.     var fltNearest : float = 9999.9999; // Farther, to start, than is possible in my game.
  89.     var vec3 : Vector3;
  90.     var vecTree : Vector3;
  91.     var intNearestPntr : int;
  92.  
  93.     // Test the flag
  94.     if (pbooCollideWithTrees == true)
  95.     {
  96.        // Find the nearest tree to the flier
  97.        for (L = 0; L < paryTrees.length; L++)
  98.        {
  99.          // Get the tree instance
  100.          triTree = paryTrees[L];
  101.          // Get the normalized tree position
  102.          vecTree = triTree.position;
  103.          // Get the world coordinates of the tree position
  104.          vec3 = (Vector3.Scale(pvecTerrainSize, vecTree) + pvecTerrainPosition);
  105.          // Calculate the proximity
  106.          fltProximity = Vector3.Distance(vecFlier, vec3);
  107.          // Nearest so far?
  108.          if (fltProximity < fltNearest)
  109.          {
  110.           // Remember the nearest
  111.           fltNearest = fltProximity;
  112.           // Remember the index
  113.           intNearestPntr = L;
  114.          }
  115.        }
  116.        // Get the closest tree
  117.        triTree = paryTrees[intNearestPntr];
  118.        // Get the normalized tree position of the closest tree
  119.        vecTree = triTree.position;
  120.        // Get the world coordinates of the tree position
  121.        vec3 = (Vector3.Scale(pvecTerrainSize, vecTree) + pvecTerrainPosition);
  122.        // Scale the capsule having the capsule collider that represents a solid tree
  123.        pgobTreeCollide.transform.localScale = (pvecCollideScale * triTree.heightScale);
  124.        // Add some height to position the capsule correctly on the tree
  125.        vec3.y += pgobTreeCollide.transform.localScale.y;
  126.        // Position the capsule having the capsule collider at the nearest tree
  127.        pgobTreeCollide.transform.position = vec3;
  128.     }
  129. }
Advertisement
Add Comment
Please, Sign In to add comment