Unity3D使用脚本动态创建、调用动画

需求场景:由若干个数量不确定的物体从上到下排列,需要间隔0.1s依次从左到右移动到某个位置,然后返回一小段距离。

分析:使用Unity3D的动画系统很容易实现这个功能,但是物体数量不确定,考虑将其绑定到同一个物体下,为这个物体动态创建Animation、AnimationClip(一个Animation可以含有多个动作,即AnimationClip,但我们只需要一个动作),然后针对各个子物体创建不同的AnimationCurve,最后调用这个Animation,即可实现各个物体先后按照设定的移动动画进行运动。

代码:

    class testAnim
    {
        private Animation _animation = null;

        public GameObject Target = null;    //目标对象
        public GameObject[] Items = null;   //目标对象子对象数组
        public float[] PosY = null;         //目标对象子对象的Y坐标

        public float AnimDuration = 0.3f;   //动画所用时间
        public float AnimBackTime = 0.1f;   //动画返回所用时间
        public float AnimInterval = 0.1f;   //相邻物体间动画间隔
        public float InitXPos = -25;        //X坐标初始化位置
        public float MaxXPos = 90;          //X坐标最大位置
        public float DestXPos = 60;         //X坐标目标位置

        // Use this for initialization
        void Start()
        {
            if (Target == null || Items == null || Items.Length <= 0 || Items.Length != PosY.Length)
            {
                return;
            }

            _animation = Target.AddComponent<Animation>();

            var clip = new AnimationClip()
            {
                name = "test",
                legacy = true,
                wrapMode = WrapMode.Once
            };

            for (var i = 0; i < Items.Length; i++)
            {
                var item = Items[i];
                if (item == null)
                {
                    continue;
                }

                var relativePath = item.name;

                //创建X轴动画
                var curve = new AnimationCurve();
                curve.AddKey(new Keyframe(0, InitXPos));                                                //初始状态
                curve.AddKey(new Keyframe(0 + AnimInterval * i, InitXPos));                             //暂停关键帧
                curve.AddKey(new Keyframe(0 + AnimInterval * i + AnimDuration, MaxXPos));               //运动关键帧
                curve.AddKey(new Keyframe(AnimInterval * i + AnimDuration + AnimBackTime, DestXPos));   //返回关键帧
                clip.SetCurve(relativePath, typeof(RectTransform), "m_AnchoredPosition.x", curve);

                //创建Y轴动画
                curve = new AnimationCurve();
                curve.AddKey(new Keyframe(0, PosY[i]));
                curve.AddKey(new Keyframe(AnimDuration + AnimInterval * i, PosY[i]));
                clip.SetCurve(relativePath, typeof(RectTransform), "m_AnchoredPosition.y", curve);

                //创建Scale动画
                curve = new AnimationCurve();
                curve.AddKey(new Keyframe(0, 0));                               //初始状态
                curve.AddKey(new Keyframe(0 + AnimInterval * i, 0));            //暂停状态
                curve.AddKey(new Keyframe(AnimInterval * i + AnimDuration, 1)); //运动状态
                clip.SetCurve(relativePath, typeof(RectTransform), "m_Scale.x", curve);
                clip.SetCurve(relativePath, typeof(RectTransform), "m_Scale.y", curve);
            }

            _animation.AddClip(clip, clip.name);
            _animation.Play(clip.name);
        }
    }

Points:

(1)每个动画(Animation)可以包含多个片段(AnimationClip),这里只需要一个;

(2)每个片段包含多条曲线(AnimationCurve),每条曲线描述了哪个物体(relativePath)的哪个属性(例如RectTransform的m_AnchoredPosition.x,表示锚点位置X轴的变化)怎么运动;

(3)每个动作曲线(AnimationCurve)含有多个关键帧(Keyframe),表示运动的变化情况,例如X轴坐标从(0秒,位置0)移动到(0.3s,位置90),再移动到(0.4s,位置60);

(4)重要的一点是,在描述例如RectTransform类型的属性时,需要使用“m_AnchoredPosition.x”的形式,参考“解决AnimationClip.SetCurve RectTransform Color参数 出现Missing!的情况”。

猜你喜欢

转载自blog.csdn.net/pigautumn/article/details/81781403