Why is this happening?

I’m trying to collapse a tree and create it in a random place as you can see, it spawns in a random place, but the animation is weird.
Sometimes it works, sometimes it doesn’t.
Even if it works, it is not where it should be. It comes to a random place, works and then disappears.
Here are my codes:

This codes is in my Cylinders(trees).

201695-unity-codes2.png

And this one is in my Player(tractor)

I see a few problems.

First big one is that you set the animator to play an animation and then in the same frame disable the animator then enable it again. You should do that only at the end of the play time of the animation if you do it at all. You shouldn’t need to do that if the animation doesn’t loop and it’s just getting set to true again anyway in LateUpdate. This is why your animation doesn’t play.

Second. Your LateUpdate method is a mess. Why are you using a static int initialised as 5 and tehn decrementing it once on collision and incrementing it once in LateUpdate. This code will only run once. I suspect you are trying to make it run 5 times, in which case you can just have a function that has a for loop in it that creates 5 trees in random positions and then deletes itself. You can do this in a coroutine if you really need that delay. Using that static variable is overly convoluted. You can call any public function from another object as long as you have a reference, which you do from the hit Collision in the OnCollisionEnter.

Try something like this:

// drag your prefab in in editor so you don't risk weirdness by copying an active gameobject.
public GameObject TreePrefab;
//an public int so you can tweak spawned tree number from editor
public int TreesToSpawn;
//The floor height so it can be changed from editor easily.
public float FloorHeight = 5;
//Set the time of the animation here. Ideally you would get the animator and wait that specific time rather than set a number in code but I don't have enough information about your animator states etc.
public float animTime = 0.6f

//Public coroutine so that it can be called from the player when you collide.
public IEnumerator Despawn()
{
    //Important ordering. Animation, then waiting for animation to play, then spawn new trees, then destroy this one
    GetComponent<Animator>().Play("TreeDie");
    yield return new WaitForSeconds(animTime);
    SpawnTrees(TreesToSpawn);
    Destroy(gameobject);
}

// A simple method for spawning your trees in one go rather than spread out over multiple frames. Can be used for any number of tree spawns.
private void SpawnTrees(int newtrees)
{
    //this loop runs the number of times specified by the TreesToSpawn variable
    for(int i = 0; i < newTrees; i++)
    {
        Vector3 randomPosition = new Vector3(Random.Range(-20, 20), FloorHeight, Random.Range(-20, 20));
        Instantiate(TreePrefab, randomPosition, Quaternion.identity);
    }
}

Then in your player script change the OnCollisionEnter to be something like:

private void OnCollisionEnter(Collision hit)
{
    //this line is optional it's here to make the rest easier to read and write. You can leave it as hit.gameObject as long as you keep using it the same way. It is slightly slower though.
    GameObject collidingObject = hit.gameObject;

    if(collidingObject.CompareTag("Trees"))
    {
        StartCoroutine(collidingObject.Despawn())
    }
}

And finally some notes on your general code style and readability. It’s hard to read your code. Keep your naming conventions consistent. TredieAndanimation should be TreeDieAndAnimation. Avoid enabling and disabling things when you don’t need to. Avoid “magic numbers” in your code so you put everything in a variable and have no random numbers or strings in your code you have to figure out the meaning of later.