Home > database >  c#/Unity: Infinite Loop Issue... Am I going crazy?
c#/Unity: Infinite Loop Issue... Am I going crazy?

Time:05-31

So, c# noob here, with a bit of an issue:

I'm trying to script a boss battle for my Unity game, and I'm making it's A.I. Every 10 seconds, I want the boss to check a random number. If it makes it, it will perform a teleport animation, and teleport. I haven't coded the teleportation itself, just trying to get the animation to trigger. I want this to be keep going throughout the boss fight, until the boss is defeated.

Unfortunately, it's an infinite loop that crashes my Unity every time I run it. I know having it in Update() is a dumb idea, but I've tried a lot of stuff and got nothing. I'm losing my mind here! Am I missing something obvious?!

Anyway, here's the code:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmellseerAI : MonoBehaviour
{
    public Animator animator;
    public SmellseerHealth smellseerhealth;
    public GameObject tele1;
    public GameObject tele2;
    public GameObject tele3;
    public DateTime TimeOfLastTeleport;
    private bool teleporting = false;
    void Start()
    {
        TimeOfLastTeleport = System.DateTime.Now;

    }
    void Update()
    {

        Debug.Log("Starting teleportcheck!");
        int TeleportMin = 1;
        int TeleportMax = 10;
        int RandomTeleport = UnityEngine.Random.Range(TeleportMin, TeleportMax);
        var diffInSeconds = (System.DateTime.Now - TimeOfLastTeleport).TotalSeconds;

        Debug.Log("diffInSeconds is "   diffInSeconds);
        if ((RandomTeleport > 5) && (diffInSeconds > 3))
        {
            Debug.Log("Teleporting!");

            teleporting = true;
            animator.SetBool("teleporting", true);
            while (animator.GetCurrentAnimatorStateInfo(0).normalizedTime <= 1)
            {  //If normalizedTime is 0 to 1 means animation is playing, if greater than 1 means finished
                Debug.Log("anim playing");
            }
            animator.SetBool("teleporting", false);
            TimeOfLastTeleport = System.DateTime.Now;
        }
        else
        {
            Debug.Log("Failed to teleport");
        }
        Debug.Log("Gaming!");

    }
}

CodePudding user response:

You're running a while loop inside Update():

while (animator.GetCurrentAnimatorStateInfo(0).normalizedTime <= 1)

but the animator's time isn't changing because it updates each frame, and you're causing the main thread to hang with your while loop. You won't release Update() (and thus won't allow the next frame to be drawn) until your while loop breaks, but your while loop's condition requires more frames. So you just wait forever.

Try moving your teleport values to the class, initialize them in Start(), then re-set them again after you've done all your checks. Then you can return each frame your condition isn't met. Consider the following:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmellseerAI : MonoBehaviour
{
    public Animator animator;
    public SmellseerHealth smellseerhealth;
    public GameObject tele1;
    public GameObject tele2;
    public GameObject tele3;
    public DateTime TimeOfLastTeleport;
    private bool teleporting = false;
    
    // NEW
    int TeleportMin = 1;
    int TeleportMax = 10;
    int RandomTeleport;

    void Start()
    {
        TimeOfLastTeleport = System.DateTime.Now;
        //NEW
        RandomTeleport = UnityEngine.Random.Range(TeleportMin, TeleportMax);    
    }
    void Update()
    {
        var diffInSeconds = (System.DateTime.Now - TimeOfLastTeleport).TotalSeconds;

        Debug.Log("diffInSeconds is "   diffInSeconds);
        if ((RandomTeleport > 5) && (diffInSeconds > 3))
        {
            Debug.Log("Teleporting!");

            teleporting = true;
            animator.SetBool("teleporting", true);
            // NEW
            if (animator.GetCurrentAnimatorStateInfo(0).normalizedTime <= 1)
            {  //If normalizedTime is 0 to 1 means animation is playing, if     greater than 1 means finished
                Debug.Log("anim playing");
                // NEW
                return;
            }
            animator.SetBool("teleporting", false);
            TimeOfLastTeleport = System.DateTime.Now;
        }
        else
        {
            Debug.Log("Failed to teleport");
        }
        Debug.Log("Gaming!");
        
        // NEW
        RandomTeleport = UnityEngine.Random.Range(TeleportMin, TeleportMax);    
}
}

CodePudding user response:

When you start the animation your code enters the while loop and never finishes, unity waits until all scripts are done before rendering the next frame, meaning the animation never finishes

Removing the while loop and just making it an if statement to check the animation state should work.

  • Related