播放并等待动画/动画师完成播放

问题描述:

在我的剧本中,当播放器位于平台顶部时,将其移动。 它工作正常。但是现在我想让它一旦弹起剪辑“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版本。

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系统

这是新的统一的动画播放系统。 应在您的新项目中使用而不是Animation API。

IEnumerator playAndWaitForAnim(GameObject target, string stateName) 
{ 
    int animLayer = 0; 

    Animator anim = target.GetComponent<Animator>(); 
    anim.Play(stateName); 

    //Wait until Animator is done playing 
    while (anim.GetCurrentAnimatorStateInfo(animLayer).IsName(stateName) && 
     anim.GetCurrentAnimatorStateInfo(animLayer).normalizedTime < 1.0f) 
    { 
     //Wait every frame until animation has finished 
     yield return null; 
    } 

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


对于专门的解决方案与碰撞回调函数(OnTriggerEnter)这个particluar问题,有两种方式paossible做到这一点:

。开始协同程序功能在触发检测后播放动画:

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"); 
} 

OR

。使所述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"); 
    } 
} 
+0

这是工作。如果我想让它上下移动,无所不能?我尝试调用OnTriggerEnter中的StartCoroutine来创建Update函数,并在Update函数中执行:if(target!= null) StartCoroutine(playAnim(target));但是这使得它只能一直向上移动,不会停下来,永不停止。 –

+0

我不明白你的意见。你能解释一下吗? – Programmer

+0

我的意思是现在的行StartCoroutine(playAnim(target));让它上下移动但只能移动一次。我想要做的是,它会继续向下移动......没有停止。 –

一种方式做到这一点,而无需在所有的手动检查是使用排队

target.GetComponent<Animation>().PlayQueued("Down", QueueMode.CompleteOthers); 

This c ode会在播放排队的动画之前等待当前正在对象上播放的任何其他动画完成。

The Unity API page regarding this topic