Search code examples
c#unity-game-engineanimationwhile-loop

While function to check if animation is running crashing Unity


I'm working on a two player fighting game, where one player can hit the other player. All hits are marked as a strike or a grab, and when an opponent is hit with a grab I want the opponent to follow the position of the first player for as long as the grab animation is playing(think a seismic toss where one player jumps and comes down, and the other is forced to follow). However, when I try that, Unity crashes (as in "the animations stop running, I can't interact with the editor, and I have to use task manager to close the editor" crashes). If a grab hitbox interacts with a player, the player being hit calls this code:

int grabAnimation = opponent.GetComponent<CharacterController>().playerAnim.GetCurrentAnimatorStateInfo(0).shortNameHash;

            while (opponent.GetComponent<CharacterController>().playerAnim.GetCurrentAnimatorStateInfo(0).shortNameHash == grabAnimation)
            {
                transform.position = opponent.transform.position + new Vector3(3f * whichSide, 0, 0);
                stopMoving = true;
            }

            TakeDamage(damage);
            DealKnockback(angle, magnitude);
            hitstun = damage * 10;
            comboCounter++;

If I replace the while loop with a for loop that goes based on the length of the animation, everything works fine, so I know it's the while loop that's the problem. I could potentially switch this to a for loop, but I need it to stop if the animation gets interrupted, which could be caused by a number of different things.It would be easier to not need to add functionality to a bunch of different areas if I can get this sorted out.

Additionally, I can put anything inside the while loop and it will crash, as I previously commented out everything in the middle and just did Debug.Log("Test") and the game stopped working. (stopMoving just turns off the players movement controls, it doesn't lock them in place, so that shouldn't be an issue).

Finally, the OnCollision that calls this is on a hitbox that is only activated on the player that is performing the attack, so it shouldn't be something where the player who is attacking is also calling this.

Any help is appreciated.


Solution

  • I guess, while loop is blocking all the other operations because none of scripts/components run in paralel. As soon as the condition of while become true, all the other scripts, components(Animator, animation etc.) will wait until while loop and method that has this loop complete. So you have an infinite loop.

    If you want to use this, i would turn it into a coroutine and put a yield return null after stopMoving = true; This will return control to unity (stop it from blocking main thread) so that other scripts/components will run normaly.