欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Unity 3D学习】控制Animator动画从随机帧开始

程序员文章站 2022-03-26 18:06:22
...

一、前提:游戏主场景有很多建筑,然后建筑上会有动画,如果存在多个同类型的建筑,就会出现多个相同动画频率一致的情况,这样子产品说体验性较差,所以考虑怎么控制动画从不同帧开始播放。

二、处理方案。

1、原理:通过设置动画状态机中的Cycle Offset,可以控制动画起始播放点,该值的区间是0到1,类型为float类型。

2、具体操作:我们首先给Animator添加一个“offset”参数,然后指定Animator状态机中所有状态使用Cycle offset属性,并且指定使用上面添加的“offset”参数。然后我们可以在动画挂上一个随机脚本,该脚本在OnEnable的时候会随机在0到1之间生成一个随机值,同时把该随机值设置为animtor的“offfset”值,即可达到效果。

三、具体代码

 1、统一处理建筑prefab动画参数

public static void HandleBuildingBlockAnimRandom()
{
    UnityEngine.Object[] selection = Selection.objects;
    foreach (var obj in selection)
    {
        Animator[] anims = ((GameObject)obj).GetComponentsInChildren<Animator>();
        for (int i = 0; i < anims.Length; i++)
        {

            UnityEditor.Animations.AnimatorController controller = (UnityEditor.Animations.AnimatorController)anims[i].runtimeAnimatorController;
            bool is_find = false;
            foreach (AnimatorControllerParameter param in controller.parameters)
            {
                if (param.name == "offset")
                {
                    is_find = true;
                    break;
                }
            }
            if (!is_find)
            {
                controller.AddParameter("offset", UnityEngine.AnimatorControllerParameterType.Float);
            }

            foreach (UnityEditor.Animations.ChildAnimatorState state in controller.layers[0].stateMachine.states)
            {
                state.state.cycleOffsetParameterActive = true;
                state.state.cycleOffsetParameter = "offset";
            }
        }
        AnimationRandom comp = ((GameObject)obj).GetComponent<AnimationRandom>();
        if (comp == null)
        {
            ((GameObject)obj).AddComponent<AnimationRandom>();
        }
    }
    AssetDatabase.Refresh();
    AssetDatabase.SaveAssets();
}

 2、随机脚本

public class AnimationRandom : MonoBehaviour {

   // Use this for initialization
   void OnEnable () {
        var animators = GetComponentsInChildren<Animator>(true);
        foreach (var anim in animators)
            anim.SetFloat("offset", Random.Range(0.0f, 1.0f));
    }
}
相关标签: Unity 3D开发