首页 > 技术文章 > U3D 动画帧事件问题

timeObjserver 2016-11-16 17:41 原文

测试版本U3D5.4。

1,为一个模型导入外部动画。为动画剪辑attack在某帧添加event,事件为 public void OnAttackEvent(){},函数体不做任何事情。

结果发现,在动画帧末尾添加事件,播放时两个动画的过渡效果没有了,去掉帧事件后正常过渡。

在动画集开始处(不超过33%)设置帧事件,不影响动画的过渡。

看来U3D的帧事件相当粗糙,不能精确的在动画集末尾帧添加事件而又不影响本动画集和下一动画集的过渡。

2,去掉has exit time,并在上面的帧事件中设置: 

using UnityEngine;
using System.Collections;
using UnityEditor;

public class testAnimEvent : MonoBehaviour {

    Animator animator;
    int[] randArr = new int[10];
    int idx = 1;
    int idxLast;
    AudioSource[] attackSound;
    // Use this for initialization
    void Start () {
        animator = GetComponent<Animator> ();
        System.Random rand = new System.Random ((int)Time.time);
        randArr [0] = 0;
        for(int i=1; i<10; i++){
            randArr [i] = rand.Next (0, 10);
            Debug.Log (randArr [i]);
        }
        attackSound = GetComponents<AudioSource> ();
    }
    
    // Update is called once per frame
    void Update () {
    
    }

    void OnAttackEvent(){
        int iSound = randArr [idxLast] > 4 ? 1 : 0; //播放当前动画集的音效,注意idxLast
        attackSound[iSound].Play ();
        animator.SetInteger ("attackId", randArr[idx]);//设置下一个动画集(播放完本动画集后才会开始播放下一动画集,因为有has exit time)
        idxLast = idx;

        idx = (idx + 1) % 10;
    }
}

结果发现animator.SetInteger ("attackId", randArr[idx]);并不会立即打断当前播放而进入下一个要求的动画集。它要等到本动画集播放完了才进行切换。

3,复制Assets\Characters\ThirdPersonCharacter\Animation下的HumanoidRun.fbx到另一工程下,通过U3D察看此文件,发现不能用,如图1,正常情况应该如图2。原来是没考meta文件造成的,一般情况下meta文件没什么用,这里却例外了,可能这个文件有特殊性,不深究了。

         

      图1                    图2

4,不同人形模型间的动画可以通用,注意要在动画导入设置里rig页设置为: Animation Type : Humaniod才行。

这是最简单的动画集复用。一个人形模型可以通过引用其它人形模型的AnimationController来直接播放不属于自己的动画集和状态机,这就是动画集的retarget

5,为导入的动画使用curves : 这样状态机运行时就会从曲线上采样作为speed的值。还可以在脚本中通过animator.GetFloat("speed")来获取任意时刻speed曲线上的值。这样可以做许多事情。

 

推荐阅读