Unity 5的co例程在被告知退出时不会退出

本文关键字:退出 被告 co 例程 Unity | 更新日期: 2023-09-27 18:01:28

我正在制作一款玩家与机器人战斗的游戏,我已经执行了一些代码,使AI在满足条件时向后移动并远离玩家。然而,这样做的co例程永远循环,我不确定如何使它中断。

void Update () 
    {
        //looking at player
        playerVelocity = ((TTarget.position - previous).magnitude) / Time.deltaTime;
        previous = TTarget.position;
        GameObject thePlayer = GameObject.Find("Player");
        PlayerMovement playerMovement = thePlayer.GetComponent<PlayerMovement>();
        enemyHit = playerMovement.hitEnemy;
        if (enemyHit == false)
        {
            //enemy moving
            transform.LookAt(TTarget);
            transform.Translate(Vector3.forward * Time.deltaTime * movementSpeed);
        }
        else if (enemyHit == true)
        {
            StartCoroutine("Evade");
            //Debug.Log ("Hello");
            StopCoroutine("Evade");
        }
    }
    IEnumerator Evade()
    {
        //GameObject thePlayer = GameObject.Find("Player");
        //PlayerMovement playerMovement = thePlayer.GetComponent<PlayerMovement>();
        //enemyHit = playerMovement.hitEnemy;
        transform.Translate(Vector3.back * Time.deltaTime * movementSpeed);
        yield return new WaitForSeconds(1);
        Vector3 to = new Vector3(0, -45, 0);
        if (Vector3.Distance(transform.eulerAngles, to) > 0.01f)
        {
            transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, to, 99*Time.deltaTime);
        }
        yield break;

    }

Unity 5的co例程在被告知退出时不会退出

您的问题是您正在启动协程,然后立即停止它。

void Update () 
{
    enemyHit = playerMovement.hitEnemy;
    if (enemyHit == false)
    {
        //enemy moving
        transform.LookAt(TTarget);
        transform.Translate(Vector3.forward * Time.deltaTime * movementSpeed);
    }
    else if (enemyHit == true)
    {
        StartCoroutine("Evade");
        Debug.Log ("Back From Coroutine");
        StopCoroutine("Evade");
        Debug.Log("Stopped Coroutine");
    }
}
IEnumerator Evade()
{
    Debug.Log("Starting Coroutine");
    transform.Translate(Vector3.back * Time.deltaTime * movementSpeed);
    yield return new WaitForSeconds(1);
    Debug.Log("This is never called");
    Vector3 to = new Vector3(0, -45, 0);
    if (Vector3.Distance(transform.eulerAngles, to) > 0.01f)
    {
        transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles, to, 99*Time.deltaTime);
    }
    yield break;
}

这将输出:

Starting Coroutine
Back From Coroutine
Stopped Coroutine

我认为更好的做法是使用bool和Invoke http://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html

private bool avoidPlayer = false;
void Update () 
{
    enemyHit = playerMovement.hitEnemy;
    if (enemyHit == false)
    {
        //enemy moving
        transform.LookAt(TTarget);
        transform.Translate(Vector3.forward * Time.deltaTime * movementSpeed);
    }
    else if (enemyHit == true)
    {
        transform.Translate(Vector3.back * Time.deltaTime * movementSpeed);
        avoidPlayer = true;
    }
    // Invoke the evade function every second until we have avoided the player
    if(avoidPlayer)
        Invoke("Evade", 1);
}
void Evade()
{
    Vector3 to = new Vector3(0, -45, 0);
    if (Vector3.Distance(transform.eulerAngles, to) > 0.01f)
        transform.eulerAngles = Vector3.Lerp(
                                    transform.rotation.eulerAngles, to, 99*Time.deltaTime);
    else
        avoidPlayer = false;
}