【问题标题】:Coroutine completely freezes Unity 2020.3协程彻底冻结 Unity 2020.3
【发布时间】:2021-08-13 11:14:37
【问题描述】:

我正在制作第一人称游戏,但我无法为我的角色设置动画。我有正确的动画。我需要找到一种方法让游戏检测玩家何时刚刚降落在地面上,以便我可以播放“着陆”动画。问题是到目前为止我想到的唯一方法是使用协程。但是协程在启动时会完全冻结我的整个应用程序。我怀疑这是因为半空中的行为每帧启动一次协程。这是脚本:

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

public class PlayerAnimationHandler : MonoBehaviour
{
Animator animator;

IEnumerator LandDetect()  
{
    while (!playermove.isGrounded)
    {
        animator.SetBool("Midair", true);
    }
    animator.SetTrigger("Land");
    yield return null;
}

PlayerMove playermove;
void Start()
{
    // These are the two most important components for this 
    // script. I'll need PlayerMove for the mini-API
    // that I have in there and I'll need the animator
    // for obvious reasons.
    playermove = GetComponent<PlayerMove>();

    animator = GetComponent<Animator>();
}

// Update is called once per frame
void Update()
{
    JumpHandler();
}

void JumpHandler()
{
    if (!playermove.isGrounded)
    {
        if (playermove.doubleJumpOccur)
        {
            animator.SetTrigger("DoubleJump");
            StartCoroutine(LandDetect());
        }
        else
        {
            animator.SetBool("Midair", true);
            StartCoroutine(LandDetect());
        }
    }
    else if (playermove.jumpOccur)
    {
        animator.SetTrigger("Jump");
        StartCoroutine(LandDetect());
    }
}

}

【问题讨论】:

    标签: c# unity3d animation animator


    【解决方案1】:

    我怀疑应用程序没有离开

    while (!playermove.isGrounded)
    {
        animator.SetBool("Midair", true);
    }
    

    直到你着陆。此循环在同一帧中连续执行(这会冻结您的游戏),因为您没有跳过帧。您需要将yield return 0(0,不为空。Null 不会导致协程跳过任何帧)在其中某处,以便它可以在下一帧中恢复。也可以在方法结束时删除yield return null,此时我什么都不做

    我认为它应该是这样的:

    IEnumerator LandDetect()  
    {
        while (!playermove.isGrounded)
        {
            animator.SetBool("Midair", true);
            yield return 0;
        }
        animator.SetTrigger("Land");
    }
    

    我也不知道在这里使用协程是否是最好的选择。我通常会使用一些触发/碰撞检测来检测这样的东西。

    【讨论】:

    • 这是正确的,除了yield return 0。在协程中,Unity 并不关心你到底是什么 yield return - 如果它不是 YieldInstruction 或另一个 IEnumerator,那么值就无关紧要。 yield return null; 也产生一帧。实际上调用animator.SetBool("Midair", true); 一次就足够了,然后等到你登陆然后将其设置为animator.SetBool("Midair", false); 一次 ;)
    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 2018-03-30
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 2020-11-04
    • 2010-10-03
    • 2020-09-03
    相关资源
    最近更新 更多