Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Tree falling and finally chop tree Script!

Discussion in 'Scripting' started by Frientor, Feb 14, 2016.

  1. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    Hello.. :)
    I have script for tree falling and finally chop tree Script!
    But there is problem.. where?
    Here is expample from one developer



    This is my script
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class PickaxeChop : MonoBehaviour
    5. {
    6.     public int ChopPower;
    7.     public GameObject ChoppingWoodChips;
    8.     public GameObject[] FallingTreePrefab;
    9.     public GameObject Impact;
    10.  
    11.  
    12.     private int m_ChopDamage;
    13.     private int m_CurrentChoppingTreeIndex = -1;
    14.     // Use this for initialization
    15.     private void Start()
    16.     {
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     private void Update()
    21.     {
    22.         if (Input.GetMouseButton(0))
    23.         {
    24.             GetComponent<Animation>().Play("PickAnimation");
    25.         }
    26.     }
    27.  
    28.     public void TreeChop()
    29.     {
    30.         // Did we click/attack something?
    31.  
    32.         RaycastHit hit;
    33.         // This ray will see what is where we clicked er chopped
    34.         var impactOnScreenPosition = Camera.main.WorldToScreenPoint(Impact.transform.position);
    35.  
    36.         Ray ray = Camera.main.ScreenPointToRay(impactOnScreenPosition);
    37.          
    38.  
    39.         // Did we hit anything within 10 units?);)
    40.         if (Physics.Raycast(ray, out hit, 10.0f))
    41.         {
    42.             // Did we even click er chop on the terrain/tree?);
    43.             if (hit.collider.name != Terrain.activeTerrain.name)
    44.             {
    45.                 // We didn't hit any part of the terrain (like a tree)
    46.                 return;
    47.             }
    48.  
    49.             // We hit the "terrain"! Now, how high is the ground at that point?
    50.             float sampleHeight = Terrain.activeTerrain.SampleHeight(hit.point);
    51.  
    52.             // If the height of the exact point we clicked/chopped at or below ground level, all we did
    53.             // was chop dirt.
    54.             if (hit.point.y <= sampleHeight + 0.01f)
    55.             {
    56.                 return;
    57.             }
    58.             // We must have clicked a tree! Chop it.
    59.             // Get the tree prototype index we hit, also.
    60.             int protoTypeIndex = ChopTree(hit);
    61.             if (protoTypeIndex == -1)
    62.             {
    63.                 // We haven't chopped enough for it to fall.
    64.                 return;
    65.             }
    66.             GameObject protoTypePrefab = Terrain.activeTerrain.terrainData.treePrototypes[protoTypeIndex].prefab;
    67.        
    68.             var fallenTreeScript = protoTypePrefab.GetComponent<FallenTree>();
    69.         }
    70.     }
    71.  
    72.     // Chops down the tree at hit location, and returns the prototype index
    73.     // With some changes, this could be refactored to return the selected (or chopped) tree, and
    74.     // then either display tree data to the player, or chop it.
    75.     // The return value is the tree slot index of the tree, it is -1 if we haven't chopped the tree down yet.
    76.     private int ChopTree(RaycastHit hit)
    77.     {
    78.         TerrainData terrain = Terrain.activeTerrain.terrainData;
    79.         TreeInstance[] treeInstances = terrain.treeInstances;
    80.  
    81.         // Our current closest tree initializes to far away
    82.         float maxDistance = float.MaxValue;
    83.         // Track our closest tree's position
    84.         var closestTreePosition = new Vector3();
    85.         // Let's find the closest tree to the place we chopped and hit something
    86.         int closestTreeIndex = 0;
    87.         var closestTree = new TreeInstance();
    88.         for (int i = 0; i < treeInstances.Length; i++)
    89.         {
    90.             TreeInstance currentTree = treeInstances[i];
    91.             // The the actual world position of the current tree we are checking
    92.             Vector3 currentTreeWorldPosition = Vector3.Scale(currentTree.position, terrain.size) +
    93.                                                Terrain.activeTerrain.transform.position;
    94.  
    95.             // Find the distance between the current tree and whatever we hit when chopping
    96.             float distance = Vector3.Distance(currentTreeWorldPosition, hit.point);
    97.  
    98.             // Is this tree even closer?
    99.             if (distance < maxDistance)
    100.             {
    101.                 maxDistance = distance;
    102.                 closestTreeIndex = i;
    103.                 closestTreePosition = currentTreeWorldPosition;
    104.                 closestTree = currentTree;
    105.             }
    106.         }
    107.  
    108.         // get the index of the closest tree..in the terrain tree slots, not the index of the tree in the whole terrain
    109.         int prototypeIndex = closestTree.prototypeIndex;
    110.  
    111.         // Play our chop shound
    112.         PlayChopSound(hit.point);
    113.  
    114.         if (m_CurrentChoppingTreeIndex != closestTreeIndex)
    115.         {
    116.             //This is a different tree we are chopping now, reset the damage!
    117.             // This means we can only chop on one tree at a time, switching trees sets their
    118.             // health back to full.
    119.             m_ChopDamage = ChopPower;
    120.             m_CurrentChoppingTreeIndex = closestTreeIndex;
    121.         }
    122.         else
    123.         {
    124.             // We are chopping on the same tree.
    125.             m_ChopDamage += ChopPower;
    126.         }
    127.  
    128.    
    129.      if (m_ChopDamage >= 100)
    130.             {
    131.                 var treeInstancesToRemove = new List<TreeInstance>(terrain.treeInstances);
    132.                 // We have chopped down this tree!
    133.                 // Remove the tree from the terrain tree list
    134.                 treeInstancesToRemove.RemoveAt(closestTreeIndex);
    135.                 terrain.treeInstances = treeInstancesToRemove.ToArray();
    136.                 // Now refresh the terrain, getting rid of the darn collider
    137.                 float[,] heights = terrain.GetHeights(0, 0, 0, 0);
    138.                 terrain.SetHeights(0, 0, heights);
    139.                 // Put a falling tree in its place, tilted slightly away from the player
    140.                 var fallingTree =
    141.                     (GameObject)
    142.                     Instantiate(FallingTreePrefab[prototypeIndex], closestTreePosition,
    143.                                 Quaternion.AngleAxis(2, Vector3.right));
    144.                 fallingTree.transform.localScale = new Vector3(closestTree.widthScale * fallingTree.transform.localScale.x,
    145.                                                                closestTree.heightScale * fallingTree.transform.localScale.y,
    146.                                                                closestTree.widthScale * fallingTree.transform.localScale.z);
    147.             }
    148.             return prototypeIndex;
    149.         }
    150.  
    151.     if(m_chopDamage2 >= 100) {
    152.                 var treeInstancesToRemove = new List<TreeInstance>(terrain.treeInstances);
    153.                 // We have chopped down this tree to get trunk!
    154.                 // Remove the tree from the terrain tree list
    155.                 treeInstancesToRemove.RemoveAt(closestTreeIndex);
    156.                 terrain.treeInstances = treeInstancesToRemove.ToArray();
    157.                 // Now refresh the terrain, getting rid of the darn collider
    158.                 float[,] heights = terrain.GetHeights(0, 0, 0, 0);
    159.                 terrain.SetHeights(0, 0, heights);
    160.                 // Put a trunk in its place after falling tree chopped down
    161.                 var TrunkTree =
    162.                     (GameObject)
    163.                     Instantiate(TrunkTreePrefab[prototypeIndex], closestTreePosition,
    164.                                 Quaternion.AngleAxis(2, Vector3.right));
    165.                TrunkTree.transform.localScale = new Vector3(closestTree.widthScale * TrunkTree.transform.localScale.x,
    166.                                                                closestTree.heightScale * TrunkTree.transform.localScale.y,
    167.                                                                closestTree.widthScale * TrunkTree.transform.localScale.z);
    168.             }
    169.             return prototypeIndex;
    170.         }
    171.  
    172.  
    173.     private void PlayChopSound(Vector3 point)
    174.     {
    175.         Instantiate(ChoppingWoodChips, point, Quaternion.identity);
    176.     }
    177. }
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    I don't understand your question. You have a script, but what is the 'where" at the end?
     
  3. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    in my script's fault, but I do not know where ..
    video that I showed as an example for this script
     
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    What's the problem? Errors? What should happen? This is a guess the error game right now
     
  5. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    here is the problem

    I do not know how to solve it
     
  6. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    You duplicated the if statement at line 151, dlete the whole thin from 151 to 170
     
  7. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    But I need the script to be functional as in the video

    Chopping tree ----> Tree falls to the ground ----> Cut tree on the ground ----> Logs
     
  8. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Then just delete the 149. line
     
  9. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    Now the problem
     
  10. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    You never ever create a variable callse m_chopDamage2
     
  11. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    exactly the same except for m_ChopDamage2
     
  12. Frientor

    Frientor

    Joined:
    Oct 5, 2013
    Posts:
    47
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class PickaxeChop : MonoBehaviour
    5. {
    6.     public int ChopPower;
    7.     public GameObject ChoppingWoodChips;
    8.     public GameObject[] FallingTreePrefab;
    9.     public GameObject Impact;
    10.  
    11.  
    12.     private int m_ChopDamage;
    13.     private int m_ChopDamage2;
    14.     private int m_CurrentChoppingTreeIndex = -1;
    15.     // Use this for initialization
    16.     private void Start()
    17.     {
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     private void Update()
    22.     {
    23.         if (Input.GetMouseButton(0))
    24.         {
    25.             GetComponent<Animation>().Play("PickAnimation");
    26.         }
    27.     }
    28.  
    29.     public void TreeChop()
    30.     {
    31.         // Did we click/attack something?
    32.  
    33.         RaycastHit hit;
    34.         // This ray will see what is where we clicked er chopped
    35.         var impactOnScreenPosition = Camera.main.WorldToScreenPoint(Impact.transform.position);
    36.  
    37.         Ray ray = Camera.main.ScreenPointToRay(impactOnScreenPosition);
    38.            
    39.  
    40.         // Did we hit anything within 10 units?);)
    41.         if (Physics.Raycast(ray, out hit, 10.0f))
    42.         {
    43.             // Did we even click er chop on the terrain/tree?);
    44.             if (hit.collider.name != Terrain.activeTerrain.name)
    45.             {
    46.                 // We didn't hit any part of the terrain (like a tree)
    47.                 return;
    48.             }
    49.  
    50.             // We hit the "terrain"! Now, how high is the ground at that point?
    51.             float sampleHeight = Terrain.activeTerrain.SampleHeight(hit.point);
    52.  
    53.             // If the height of the exact point we clicked/chopped at or below ground level, all we did
    54.             // was chop dirt.
    55.             if (hit.point.y <= sampleHeight + 0.01f)
    56.             {
    57.                 return;
    58.             }
    59.             // We must have clicked a tree! Chop it.
    60.             // Get the tree prototype index we hit, also.
    61.             int protoTypeIndex = ChopTree(hit);
    62.             if (protoTypeIndex == -1)
    63.             {
    64.                 // We haven't chopped enough for it to fall.
    65.                 return;
    66.             }
    67.             GameObject protoTypePrefab = Terrain.activeTerrain.terrainData.treePrototypes[protoTypeIndex].prefab;
    68.            
    69.             var fallenTreeScript = protoTypePrefab.GetComponent<FallenTree>();
    70.         }
    71.     }
    72.  
    73.     // Chops down the tree at hit location, and returns the prototype index
    74.     // With some changes, this could be refactored to return the selected (or chopped) tree, and
    75.     // then either display tree data to the player, or chop it.
    76.     // The return value is the tree slot index of the tree, it is -1 if we haven't chopped the tree down yet.
    77.     private int ChopTree(RaycastHit hit)
    78.     {
    79.         TerrainData terrain = Terrain.activeTerrain.terrainData;
    80.         TreeInstance[] treeInstances = terrain.treeInstances;
    81.  
    82.         // Our current closest tree initializes to far away
    83.         float maxDistance = float.MaxValue;
    84.         // Track our closest tree's position
    85.         var closestTreePosition = new Vector3();
    86.         // Let's find the closest tree to the place we chopped and hit something
    87.         int closestTreeIndex = 0;
    88.         var closestTree = new TreeInstance();
    89.         for (int i = 0; i < treeInstances.Length; i++)
    90.         {
    91.             TreeInstance currentTree = treeInstances[i];
    92.             // The the actual world position of the current tree we are checking
    93.             Vector3 currentTreeWorldPosition = Vector3.Scale(currentTree.position, terrain.size) +
    94.                                                Terrain.activeTerrain.transform.position;
    95.  
    96.             // Find the distance between the current tree and whatever we hit when chopping
    97.             float distance = Vector3.Distance(currentTreeWorldPosition, hit.point);
    98.  
    99.             // Is this tree even closer?
    100.             if (distance < maxDistance)
    101.             {
    102.                 maxDistance = distance;
    103.                 closestTreeIndex = i;
    104.                 closestTreePosition = currentTreeWorldPosition;
    105.                 closestTree = currentTree;
    106.             }
    107.         }
    108.  
    109.         // get the index of the closest tree..in the terrain tree slots, not the index of the tree in the whole terrain
    110.         int prototypeIndex = closestTree.prototypeIndex;
    111.  
    112.         // Play our chop shound
    113.         PlayChopSound(hit.point);
    114.  
    115.         if (m_CurrentChoppingTreeIndex != closestTreeIndex)
    116.         {
    117.             //This is a different tree we are chopping now, reset the damage!
    118.             // This means we can only chop on one tree at a time, switching trees sets their
    119.             // health back to full.
    120.             m_ChopDamage = ChopPower;
    121.             m_ChopDamage2 = ChopPower;
    122.             m_CurrentChoppingTreeIndex = closestTreeIndex;
    123.         }
    124.         else
    125.         {
    126.             // We are chopping on the same tree.
    127.             m_ChopDamage += ChopPower;
    128.             m_ChopDamage2 += ChopPower;
    129.         }
    130.  
    131.        
    132.      if (m_ChopDamage >= 100)
    133.             {
    134.                 var treeInstancesToRemove = new List<TreeInstance>(terrain.treeInstances);
    135.                 // We have chopped down this tree!
    136.                 // Remove the tree from the terrain tree list
    137.                 treeInstancesToRemove.RemoveAt(closestTreeIndex);
    138.                 terrain.treeInstances = treeInstancesToRemove.ToArray();
    139.                 // Now refresh the terrain, getting rid of the darn collider
    140.                 float[,] heights = terrain.GetHeights(0, 0, 0, 0);
    141.                 terrain.SetHeights(0, 0, heights);
    142.                 // Put a falling tree in its place, tilted slightly away from the player
    143.                 var fallingTree =
    144.                     (GameObject)
    145.                     Instantiate(FallingTreePrefab[prototypeIndex], closestTreePosition,
    146.                                 Quaternion.AngleAxis(2, Vector3.right));
    147.                 fallingTree.transform.localScale = new Vector3(closestTree.widthScale * fallingTree.transform.localScale.x,
    148.                                                                closestTree.heightScale * fallingTree.transform.localScale.y,
    149.                                                                closestTree.widthScale * fallingTree.transform.localScale.z);
    150.             }
    151.             return prototypeIndex;
    152.        
    153.    
    154.     if    (m_ChopDamage2 >= 100) {
    155.                 var treeInstancesToRemove = new List<TreeInstance>(terrain.treeInstances);
    156.                 // We have chopped down this tree to get trunk!
    157.                 // Remove the tree from the terrain tree list
    158.                 treeInstancesToRemove.RemoveAt(closestTreeIndex);
    159.                 terrain.treeInstances = treeInstancesToRemove.ToArray();
    160.                 // Now refresh the terrain, getting rid of the darn collider
    161.                 float[,] heights = terrain.GetHeights(0, 0, 0, 0);
    162.                 terrain.SetHeights(0, 0, heights);
    163.                 // Put a trunk in its place after falling tree chopped down
    164.                 var TrunkTree =
    165.                     (GameObject)
    166.                     Instantiate(TrunkTreePrefab[prototypeIndex], closestTreePosition,
    167.                                 Quaternion.AngleAxis(2, Vector3.right));
    168.                TrunkTree.transform.localScale = new Vector3(closestTree.widthScale * TrunkTree.transform.localScale.x,
    169.                                                                closestTree.heightScale * TrunkTree.transform.localScale.y,
    170.                                                                closestTree.widthScale * TrunkTree.transform.localScale.z);
    171.             }
    172.             return prototypeIndex;
    173.         }
    174.  
    175.  
    176.     private void PlayChopSound(Vector3 point)
    177.     {
    178.         Instantiate(ChoppingWoodChips, point, Quaternion.identity);
    179.     }
    180. }