如何使用Animator检查播放动画是否可以在两个摄像头之间切换?

时间:2017-05-08 18:24:20

标签: c# unity3d unity5

我有主摄像头。另一个相机叫它AnimationCamera。 在一个脚本中,我可以通过单击C键在两个摄像头之间切换。 但我还添加了一个播放特定动画片段的方法。我从另一个脚本中调用此方法:

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

public class AnimationCamera : MonoBehaviour
{
    public Camera animationCamera;
    public Camera mainCamera;
    Animator _anim;

    private void Start()
    {
        animationCamera.enabled = false;
        mainCamera.enabled = true;
        _anim = GetComponent<Animator>();
    }

    private void Update()
    {

        if (Input.GetKeyDown(KeyCode.C))
        {
            animationCamera.enabled = !animationCamera.enabled;
            mainCamera.enabled = !mainCamera.enabled;

            if (animationCamera.enabled)
            {
                _anim.CrossFade("Animation_Sign", 0);
            }
            else
            {
                _anim.CrossFade("Animation_Idle", 0);
            }
        }
    }

    public void PlaySignAnimation()
    {        
        animationCamera.enabled = true;
        _anim.CrossFade("Animation_Sign", 0);
    }
}

脚本我正在调用方法PlaySignAnimation:

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

public class Sign_Wooden_Blank : Interactable
{ 
    public override void Interact()
    {
        var ac = GameObject.Find("AnimationCamera").GetComponent<AnimationCamera>();
        ac.PlaySignAnimation();
    }
}

然后在Animator窗口中我有两种状态:&#34; Animation_Sign&#34;和&#34; Animation_Idle&#34;国家&#34; Animation_Idle&#34;用于停止动画。

然后我也说默认状态是空闲,我也在两个状态之间进行了转换。 我还设置动画片段不在循环中。

Animator window

问题是在脚本中如何检查或如何知道它何时完成播放剪辑以便我可以切换回相机?

public void PlaySignAnimation()
        {        
            animationCamera.enabled = true;
            _anim.CrossFade("Animation_Sign", 0);
        }

在这里我将它切换到animationCamera,使其成为true。 但是一旦动画片段完成播放并停止播放,我想将脚本切换回mainCamera,使其启用为true,并且animationCamera启用为false。

问题是我没有任何标志/标志告诉我动画播放完毕的时间。

2 个答案:

答案 0 :(得分:1)

我已经使用这种方法来管理动画控制器

enter image description here

正如你可以看到IdleClosed和ClosedToOpened之间的事务发生在变量整数&#34; stateMachine&#34;它等于1。

在我的update()方法或类似方法中,我有以下代码:

    var value = localAnimator.GetInteger ("stateMachine");

    if(value==1)
      EventDispatchManager.Instance.TriggerEvent (EventsDictionary.OPENING , sender);
    if(value==2)
      EventDispatchManager.Instance.TriggerEvent (EventsDictionary.OPENED , sender);

EventDispatchManager类是我的应用程序的简单自定义信号管理器,可以从任何类型的对象发送和接收消息。

在ClosedToOpened动画结束时,我设置了一个动画事件,它将改变&#34; stateMachine&#34; 2迁移到&#34; IdleOpened&#34;动画。

https://docs.unity3d.com/Manual/animeditor-AnimationEvents.html&lt; - 您可以在此处找到有关动画事件的文档。

使用此功能并将以下条件返回到我的代码中:

 if(value==2)

      EventDispatchManager.Instance.TriggerEvent (EventsDictionary.OPENED , this.gameObject);

所以在另一个地方我会有一个听众,就像这样......

Scripts.Managers.EventDispatchManager.Instance.StartListening (EventsDictionary.OPENED, listener: delegate {

        //DO SOMETHING WHEN THIS EVENT IS RAISED
    });

通过这种方式我管理和种情况。

答案 1 :(得分:0)

我的解决方案。

首先我得到Animator中每个动画片段的长度。 所以我有一个每个剪辑的浮动列表。

然后我将底部的方法更改为IEnumerator的类型。 在这种情况下使用WaitForSeconds,长度为10。 在脚本中,我调用此方法只是将其更改为使用StartCoroutine。

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

public class AnimationCamera : MonoBehaviour
{
    public Camera animationCamera;
    public Camera mainCamera;
    Animator _anim;
    List<float> animations = new List<float>();

    private void Start()
    {
        animationCamera.enabled = false;
        mainCamera.enabled = true;
        _anim = GetComponent<Animator>();

        foreach (AnimationClip ac in _anim.runtimeAnimatorController.animationClips)
        {
            animations.Add(ac.length);
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.C))
        {
            animationCamera.enabled = !animationCamera.enabled;
            mainCamera.enabled = !mainCamera.enabled;

            if (animationCamera.enabled)
            {
                _anim.CrossFade("Animation_Sign", 0);
            }
            else
            {
                _anim.CrossFade("Animation_Idle", 0);
            }
        }
    }

    public IEnumerator PlaySignAnimation()
    {        
        animationCamera.enabled = true;
        _anim.CrossFade("Animation_Sign", 0);
        yield return new WaitForSeconds(animations[0]);
        animationCamera.enabled = false;
        mainCamera.enabled = true;
    }
}

第二个脚本:

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

public class Sign_Wooden_Blank : Interactable
{
    public override void Interact()
    {
        var ac = GameObject.Find("AnimationCamera").GetComponent<AnimationCamera>();
        ac.StartCoroutine(ac.PlaySignAnimation());
    }
}

不确定我所做的是一个很好的解决方案,但它正在发挥作用。