Play and wait for Animation/Animator to finish playing

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

In my script i did that when the player is on the top of the platform move it up. It's working fine. But now i want to make that once it got up play the clip "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");         }     } }

After the line

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

I want when it finish playing it play the down:

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

回答1:

While both answers should work, another method of doing this with coroutine and the IsPlaying function. You use the coroutine solution if you also want to perform other task after the animation.

For the Animation system:

The old Unity animation playback system. This should not be used in your new Project unless you are still using old Unity version.

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

For the Animator system

This is the new Unity animation playback system. This should be used in your new Project instead of the 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"); }


For a solution specially for this particluar problem with the collision callback function (OnTriggerEnter), there are two paossible ways to do that:

1.Start a coroutine function to play the animation after trigger detection:

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

2.Make the OnTriggerEnter function a coroutine(IEnumerator) instead of void function:

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


回答2:

One way to do this without needing to check manually at all is to use queuing

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

This code will wait for any other animation currently playing on the object to finish before playing the queued animation.

The Unity API page regarding this topic



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!