在我的脚本中,我做到了当播放器位于平台顶部时将其向上移动。一切正常。但是现在我想使它弹起时播放剪辑“ 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函数执行此操作的另一种方法。如果您还想在动画之后执行其他任务,则可以使用协程解决方案。
IsPlaying
对于Animation系统:
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系统
Animator
这是新的Unity动画播放系统。这 应该使用 在你的新项目,而不是AnimationAPI。在性能方面,最好使用Animator.StringToHash和通过哈希数比较当前状态,而不是使用IsName比较字符串的函数,因为哈希更快。
Animator.StringToHash
IsName
比方说,你有一个名为国家的名字Jump,Move和Look。您可以如下获得它们的哈希值,然后在下面使用该函数播放和等待它们:
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)的解决方案,有两种可能的解决方法:
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函数:
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"); } }