加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 播放并等待Animation / Animator完成播放

发布时间:2020-12-15 23:35:54 所属栏目:百科 来源:网络整理
导读:在我的脚本中,当玩家位于平台顶部时,我就这样做了. 它工作正常.但是现在我想让它一旦起来播放剪辑“Down”. using UnityEngine;using System.Collections;using System.Reflection;public class DetectPlayer : MonoBehaviour { GameObject target; public v
在我的脚本中,当玩家位于平台顶部时,我就这样做了.
它工作正常.但是现在我想让它一旦起来播放剪辑“Down”.

using UnityEngine;
using System.Collections;
using System.Reflection;

public class DetectPlayer : MonoBehaviour {

    GameObject target;

    public void ClearLog()
    {
        var assembly = Assembly.GetAssembly(typeof(UnityEditor.ActiveEditorTracker));
        var type = assembly.GetType("UnityEditorInternal.LogEntries");
        var method = type.GetMethod("Clear");
        method.Invoke(new object(),null);
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.name == "Platform")
        {
            Debug.Log("Touching Platform");
        }

    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.name == "OnTop Detector")
        {
            Debug.Log("On Top of Platform");
            GameObject findGo = GameObject.Find("ThirdPersonController");
            GameObject findGo1 = GameObject.Find("Elevator");
            findGo.transform.parent = findGo1.transform;
            target = GameObject.Find("Elevator");
            target.GetComponent<Animation>().Play("Up");
        }
    }
}

行后

target.GetComponent<Animation>().Play("Up");

我想当它完成播放时播放下来:

target.GetComponent<Animation>().Play("Down");

解决方法

虽然两个答案都应该有效,但另一种方法是使用协同程序和IsPlaying函数执行此操作.如果您还想在动画后执行其他任务,则使用协同程序解决方案.

对于Animation系统:

旧的Unity动画播放系统.除非您仍在使用旧的Unity版本,否则不应在新项目中使用此项.

IEnumerator playAndWaitForAnim(GameObject target,string clipName)
{
    Animation anim = target.GetComponent<Animation>();
    anim.Play(clipName);

    //Wait until Animation is done Playing
    while (anim.IsPlaying(clipName))
    {
        yield return null;
    }

    //Done playing. Do something below!
    Debug.Log("Done Playing");
}

对于Animator系统

这是新的Unity动画播放系统.这应该在您的新项目而不是Animation API中使用.在性能方面,最好使用Animator.StringToHash并将当前状态与散列数进行比较,而不是比较字符串的IsName函数,因为散列是faster.

假设您有名为Jump,Move和Look的州名.你得到如下所示的哈希值,然后使用该功能进行播放并在下面等待它们:

const string animBaseLayer = "Base Layer";
int jumpAnimHash = Animator.StringToHash(animBaseLayer + ".Jump");
int moveAnimHash = Animator.StringToHash(animBaseLayer + ".Move");
int lookAnimHash = Animator.StringToHash(animBaseLayer + ".Look");

public IEnumerator PlayAndWaitForAnim(Animator targetAnim,string stateName)
{
    //Get hash of animation
    int animHash = 0;
    if (stateName == "Jump")
        animHash = jumpAnimHash;
    else if (stateName == "Move")
        animHash = moveAnimHash;
    else if (stateName == "Look")
        animHash = lookAnimHash;

    //targetAnim.Play(stateName);
    targetAnim.CrossFadeInFixedTime(stateName,0.6f);

    //Wait until we enter the current state
    while (targetAnim.GetCurrentAnimatorStateInfo(0).fullPathHash != animHash)
    {
        yield return null;
    }

    float counter = 0;
    float waitTime = targetAnim.GetCurrentAnimatorStateInfo(0).length;

    //Now,Wait until the current state is done playing
    while (counter < (waitTime))
    {
        counter += Time.deltaTime;
        yield return null;
    }

    //Done playing. Do something below!
    Debug.Log("Done Playing");

}

对于专门针对碰撞回调函数(OnTriggerEnter)的特定问题的解决方案,有两种可能的方法:

1.启动协同功能,在触发检测后播放动画:

void OnTriggerEnter(Collider other)
{
    if (other.gameObject.name == "OnTop Detector")
    {
        Debug.Log("On Top of Platform");
        GameObject findGo = GameObject.Find("ThirdPersonController");
        GameObject findGo1 = GameObject.Find("Elevator");
        findGo.transform.parent = findGo1.transform;
        target = GameObject.Find("Elevator");
        StartCoroutine(playAnim(target));
    }
}

IEnumerator playAnim(GameObject target)
{
    Animation anim = target.GetComponent<Animation>();
    anim.Play("Up");

    //Wait until Up is done Playing the play down
    while (anim.IsPlaying("Up"))
    {
        yield return null;
    }

    //Now Play Down
    anim.Play("Down");
}

要么

2.使OnTriggerEnter函数成为协程(IEnumerator)而不是void函数:

IEnumerator OnTriggerEnter(Collider other)
{
    if (other.gameObject.name == "OnTop Detector")
    {
        Debug.Log("On Top of Platform");
        GameObject findGo = GameObject.Find("ThirdPersonController");
        GameObject findGo1 = GameObject.Find("Elevator");
        findGo.transform.parent = findGo1.transform;
        target = GameObject.Find("Elevator");
        Animation anim = target.GetComponent<Animation>();
        anim.Play("Up");

        //Wait until Up is done Playing the play down
        while (anim.IsPlaying("Up"))
        {
            yield return null;
        }

        //Now Play Down
        anim.Play("Down");
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读