I'm making a boss and I have some code that's supposed to make it spin for 5 seconds and then stop spinning. Only problem is the fact that the loop I'm using for this just crashes unity I've tried browsing for an answer, I found a thread that says unity will crash if the loop never ends, so I checked and realized my loop was indeed never going to reach the end because the statement that modified the variable to stop the loop was outside the loop so i fixed that but it still crashes. Code: Code (CSharp): public class Spin : StateMachineBehaviour { private float damage; [SerializeField] private float spinDura = 5; private Breserker breserker; private Axe_Spin axeSpinHitbox; // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { breserker = animator.GetComponent<Breserker>(); axeSpinHitbox = breserker.transform.Find(breserker.axeSpinHitboxName).GetComponent<Axe_Spin>(); axeSpinHitbox.Spin(spinDura); } // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { } // OnStateExit is called when a transition ends and the state machine finishes evaluating this state override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { } Axe spin hitbox.Spin() Code (CSharp): public void Spin(float spinDura) { spinning = true; StartCoroutine(SpinTimer(spinDura)); while (spinning) { breserker.transform.Rotate(new(0, spinSpeed, 0)); } } public IEnumerator SpinTimer(float spinDura) { yield return new WaitForSeconds(spinDura); spinning = false; }
Hi, Here, you have an infinite loop that you're trying to stop later in the application. The problem is that Unity is executing your while loop during the frame, and it has no end on this current frame, so there is no way for Unity to render the frame after the code execution, because the while loop never ends. If you want code to be executed at every frame on MonoBehaviour's objects in Unity, you have to use the Update function. A better way to do this for you is to call inside the Update function a function called UpdateSpin, where you check you're spinning boolean value, if you're spinning the berserker or not. In order to wait for seconds to stop spinning, you can create a float variable, that you will increment (or decrement) by Time.deltaTime. After that, when your float reaches the limit, you can stop spinning.
Unity will lock up 100% of the time EVERY millisecond your scripting code is running. Nothing will render, no input will be processed, no Debug.Log() will come out, no GameObjects or transforms will appear to update. Absolutely NOTHING will happen... until your code either: - returns from whatever function it is running - yields from whatever coroutine it is running As long as your code is looping, Unity isn't going to do even a single frame of change. Nothing. No exceptions. "Yield early, yield often, yield like your game depends on it... it does!" - Kurt Dekker
Your code had an infinite loop for the reasons mentioned above. Code (csharp): public IEnumerator Spin(float spinDura) { float elapsedTime = 0f; while (elapsedTime < spinDura) { breserker.transform.Rotate(0f, spinSpeed * Time.deltaTime, 0f); elapsedTime += Time.deltaTime; yield return null; } } You can then start the coroutine from the state machine behaviour. Code (csharp): axeSpinHitbox.StartCoroutine(axeSpinHitbox.Spin(spinDura));