Unity引擎模拟实现HTML5 animation 动画效果,取代NGUI的Tweener缓动

#region Namespaces
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
#endregion


namespace Hstj
{
    #region 对象类
    public class TargetObj
    {
        public const float PRECISION = 0.00001f;
        #region 变化曲线
        // X轴变化量
        public AnimationCurve OffsetXValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,0.0f),new Keyframe(1.0f,1.0f)}
        // Y轴变化量
        public AnimationCurve OffsetYValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,0.0f),new Keyframe(1.0f,1.0f)}
        // Z轴变化量
        public AnimationCurve OffsetZValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,01.0f),new Keyframe(1.0f,1.0f)}
        // Alpha变化量
        public AnimationCurve AlphaValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,1.0f,0f,0f),new Keyframe(1.0f,1.0f,1f,1f)}
        // 缩放变化量
        public AnimationCurve ScaleXValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,1.0f,1f,1f),new Keyframe(1.0f,1.0f,1f,1f)}
        public AnimationCurve ScaleYValueCurve = new AnimationCurve();
        public AnimationCurve ScaleZValueCurve = new AnimationCurve();
        // 旋转变化量
        public AnimationCurve RotateXValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,1.0f,1f,1f),new Keyframe(1.0f,1.0f,1f,1f)}
        public AnimationCurve RotateYValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,1.0f,1f,1f),new Keyframe(1.0f,1.0f,1f,1f)}
        public AnimationCurve RotateZValueCurve = new AnimationCurve();//new Keyframe[]{new Keyframe(0f,1.0f,1f,1f),new Keyframe(1.0f,1.0f,1f,1f)}
        // 速率
        public AnimationCurve SpacePercentCurve = new AnimationCurve(new Keyframe[]{new Keyframe(0f,0f),new Keyframe(1.0f,1.0f)});
        // 颜色变化量
        public AnimationCurve ColorRValueCurve = new AnimationCurve();//new Keyframe[] { new Keyframe(0f, 1f,1f,1f), new Keyframe(1.0f, 1.0f,1f,1f) }
        public AnimationCurve ColorGValueCurve = new AnimationCurve();
        public AnimationCurve ColorBValueCurve = new AnimationCurve();
        #endregion


        // Public 
        public Transform _target = null;
       
        //Private
        private float duration = 0f;             //运行时间
        //private float delay = 0f;              //延时
        private float startTime = 0;             //开始时间(加上延时)
        private float percent = 0f;              //进度
        bool isfinish = false;
        bool isValueBySpace = false;              //数值由速度控制(keyframes 是from - to格式的)
        bool isLocal = true;                     //是否改变相对量


        //变化量    注:数组(0:起始值,1:终点值,2:中间量)
        private Vector3[] vecsPos = new Vector3[3];              //位置变化
        private Vector3[] vecsRote = new Vector3[3];             //角度变化
        private Vector3[] vecsScale = new Vector3[3];            //缩放变化        
        private Vector3[] colors = new Vector3[3];               //颜色变化(0 ~1)
        private float[] alphasVal = new float[3];                //透明度变化


        Vector3 offsetPos = Vector3.zero;
        Vector3 offsetRotate = Vector3.zero;
        Vector3 offsetScale = Vector3.one;
        float alphaPerValue = 0f;
        float spacePerValue = 0;


        #region 提供给外部取值接口


        public float Duration
        {
            get { return duration; }
            set {
                duration = value;
                percent = 0;
                isfinish = false;
            }
        }
        public bool IsFinish
        {
            get { return isfinish; }
        }
        public float Percent
        {
            get { return percent; }
        }


        #endregion
        //


        #region 执行模块
        //更新函数
        public void Update()
        {
            if (_target == null)
            {
                isfinish = true;
                return;
            }
            if (isfinish)
                return;
            
            if (Time.time < startTime)
            {
                return;
            }


            float runtime = Time.time - startTime;
            percent = runtime / duration;
            if (percent > 1.0f)
            {
                percent = 1.0f;
                isfinish = true;
            }


            ExecuteTweenChange();
        }


        void ExecuteTweenChange()
        {
            if (_target == null)
            {
                isfinish = true;
                return;
            }
            
            if( isValueBySpace )  //数值由速度控制
            {
                spacePerValue = SpacePercentCurve.Evaluate(percent);


                vecsPos[2] = vecsPos[0] + (vecsPos[1] - vecsPos[0]) * spacePerValue;
                vecsRote[2] = vecsRote[0] + (vecsRote[1] - vecsRote[0]) * spacePerValue;
                vecsScale[2] = vecsScale[0] + (vecsScale[1] - vecsScale[0]) * spacePerValue;
                if (isLocal == false)
                {
                    _target.position = vecsPos[2];
                    _target.rotation = Quaternion.Euler(vecsRote[2]);
                }
                else
                {
                    _target.localPosition = vecsPos[2];
                    _target.localRotation = Quaternion.Euler(vecsRote[2]);
                }
                _target.localScale = vecsScale[2];


                UIWidget widght = _target.GetComponent<UIWidget>();
                if (widght != null)
                {
                    alphasVal[2] = alphasVal[0] + (alphasVal[1] - alphasVal[0]) * spacePerValue;
                    colors[2] = colors[0] + (colors[1] - colors[0]) * spacePerValue;                    
                    widght.color = new Color(colors[2].x, colors[2].y, colors[2].z);
                    widght.alpha = alphasVal[2];
                }
            }
            else{
                offsetPos.x = OffsetXValueCurve.Evaluate(percent);
                offsetPos.y = OffsetYValueCurve.Evaluate(percent);
                offsetPos.z = OffsetZValueCurve.Evaluate(percent);
                alphaPerValue = AlphaValueCurve.Evaluate(percent);
                offsetScale.x = ScaleXValueCurve.Evaluate(percent);
                offsetScale.y = ScaleYValueCurve.Evaluate(percent);
                offsetScale.z = ScaleZValueCurve.Evaluate(percent);
                offsetRotate.x = RotateXValueCurve.Evaluate(percent);
                offsetRotate.y = RotateYValueCurve.Evaluate(percent);
                offsetRotate.z = RotateZValueCurve.Evaluate(percent);


                colors[2].x = ColorRValueCurve.Evaluate(percent);
                colors[2].y = ColorGValueCurve.Evaluate(percent);
                colors[2].z = ColorBValueCurve.Evaluate(percent);


                vecsPos[2] = offsetPos;
                if (OffsetXValueCurve.keys.Length > 0 && OffsetYValueCurve.keys.Length >0)
                {
                    if (isLocal == false)
                        _target.position = vecsPos[2];
                    else
                        _target.localPosition = vecsPos[2];
                }




                vecsRote[2] = offsetRotate;
                if (RotateXValueCurve.keys.Length > 0 && RotateYValueCurve.keys.Length > 0)
                {
                    if (isLocal == false)
                        _target.rotation = Quaternion.Euler(vecsRote[2]);
                    else
                        _target.localRotation = Quaternion.Euler(vecsRote[2]);
                }




                vecsScale[2] = offsetScale;//vecsScale[0] + (vecsScale[1] - vecsScale[0]) * scalePerValue;
                if(ScaleXValueCurve.keys.Length >0)
                    _target.localScale = vecsScale[2];


                UIWidget widght = _target.GetComponent<UIWidget>();
                if (widght != null)
                {
                    if (ColorRValueCurve.keys.Length > 0)
                    {
                        widght.color = new Color(colors[2].x, colors[2].y, colors[2].z);
                    }
                    alphasVal[2] = alphaPerValue;
                    if (AlphaValueCurve.keys.Length > 0)
                    {
                        widght.alpha = alphasVal[2];
                    }
                }
            }
        }


        #endregion


       
        
        #region 赋值模块
        // 外部调用赋值
        // hashDate :封装的是物体的移动属性
        //animation属性:封装着时间,运动速度,延时等
        //keyframes关键帧属性,有(from- to)和百分比 两种格式,每一帧中封装 位置、alpha、颜色、缩放、旋转等参数
        //返回值 0:没有错误,1:对象时空引用,2:hash表示空值
        public int AssighmentValue(Transform target, Hashtable hashDate)
        {
            if (target == null)
            {
                Debug.LogError("unexpected erroe: operate target is null");
                return 1;
            }
            _target = target;


            if (hashDate.Count == 0)
            {
                Debug.LogError("unexpected erroe: hashDate is null");
                return 2;
            }
            AnalysisHashDate(hashDate);


            return 0;
        }


        void AnalysisHashDate(Hashtable hashDate)
        {
            //解析animation 属性            
            Hashtable animation = hashDate["animation"] as Hashtable;
            AdaptAnimationDate(animation);            
            
            //解析keyframes属性
            Hashtable keyframes = hashDate["keyframes"] as Hashtable;
            AdaptKeyframesDate(keyframes);
        }


        //解析animation 属性
        void AdaptAnimationDate(Hashtable hashTable)
        {
            if (hashTable.Count == 0 || hashTable == null)
            {
                Debug.LogError("animation is null,please check");
                return;
            }


            if (hashTable.ContainsKey("duration"))
                duration = (float)hashTable["duration"];
            else
                duration = 1.0f;
            if (hashTable.ContainsKey("delay"))
            {
                startTime = Time.time + (float)hashTable["delay"];
            }
            else
                startTime = Time.time;
            if (hashTable.Contains("islocal"))
            {
                isLocal = (bool)hashTable["islocal"];
            }
            else
            {
                isLocal = true;
            }


            //速度变化控制
            if (hashTable.ContainsKey("time_function"))
            {
                isValueBySpace = true;
                string type = hashTable["time_function"].ToString();
                if (type.CompareTo("linear") == 0)
                {
                    SpacePercentCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0f, 0f, 1f, 1f), new Keyframe(1.0f, 1.0f, 1f, 1f) });
                }
                else if (type.CompareTo("ease") == 0 || type.CompareTo("ease-in-out") == 0)
                {
                    SpacePercentCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0f, 0f, 0f, 0f), new Keyframe(1.0f, 1.0f, 0f, 0f) });
                }
                else if (type.CompareTo("ease-in") == 0)
                {
                    SpacePercentCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0f, 0f, 0f, 0f), new Keyframe(1.0f, 1.0f, 2f, 2f) });
                }
                else if (type.CompareTo("ease-out") == 0)
                {
                    SpacePercentCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0f, 0f, 2f, 2f), new Keyframe(1.0f, 1.0f, 0f, 0f) });
                }
                else if (type.CompareTo("cubic-bezier") == 0)
                {
                    if (hashTable.Contains("values"))
                    {
                        Keyframe[] keyframes = (Keyframe[]) hashTable["values"];
                        foreach (Keyframe keyframe in keyframes)
                        {
                            SpacePercentCurve.AddKey(keyframe);
                        }
                    }
                }


            }
            else
            {
                isValueBySpace = false;
                SpacePercentCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0f, 0f,1f,1f), new Keyframe(1.0f, 1.0f,1f,1f) });
            }


            if (isLocal)
            {
                vecsPos[0] = _target.localPosition;
                Vector3 tempRote = Vector3.zero;
                tempRote.x = _target.localRotation.x;
                tempRote.y = _target.localRotation.y;
                tempRote.z = _target.localRotation.z;
                vecsRote[0] = tempRote;
                vecsScale[0] = _target.localScale;
            }
            else
            {
                vecsPos[0] = _target.position;
                Vector3 tempRote = Vector3.zero;
                tempRote.x = _target.rotation.x;
                tempRote.y = _target.rotation.y;
                tempRote.z = _target.rotation.z;
                vecsRote[0] = tempRote;
                vecsScale[0] = _target.localScale;
            }
            alphasVal[0] = 1f;
            colors[0] = Vector3.one;  
            UIWidget widght = _target.GetComponent<UIWidget>();
            if (widght != null)
            {
                alphasVal[0] = widght.alpha;
                alphasVal[1] = alphasVal[0];
                colors[0].x = widght.color.r;
                colors[0].y = widght.color.g;
                colors[0].z = widght.color.b;
                colors[1] = colors[0];
             }
                          
        }


        //解析keyframes属性
        void AdaptKeyframesDate(Hashtable hashTable)
        {
            if (hashTable.Count == 0 || hashTable == null)
            {
                Debug.LogError("keyframes is null,please check");
                return;
            }
            if (hashTable.Contains("from"))
            {
                isValueBySpace = true;
                Hashtable start = (Hashtable)hashTable["from"];
                Hashtable end = (Hashtable)hashTable["to"];
                if (end == null)
                    end = start;
                if (start.Contains("pos"))
                    vecsPos[0] = (Vector3)start["pos"];
                if (end.Contains("pos"))
                    vecsPos[1] = (Vector3)end["pos"];


                if (start.Contains("scale"))
                    vecsScale[0] = (Vector3)start["scale"];
                if (end.Contains("scale"))
                    vecsScale[1] = (Vector3)end["scale"];


                if (start.Contains("rotate"))
                    vecsRote[0] = (Vector3)start["rotate"];
                if (end.Contains("rotate"))
                    vecsRote[1] = (Vector3)end["rotate"];


                if (start.Contains("alpha"))
                    alphasVal[0] = (float)start["alpha"];
                if (end.Contains("alpha"))
                    alphasVal[1] = (float)end["alpha"];
                //Debug.LogWarning("******alpha" + alphasVal[0] + "  " + alphasVal[1]);
                if (start.Contains("color"))
                {
                    Vector3 vec = (Vector3)(start["color"]);
                    colors[0] = (Vector3)(start["color"]) / 255.0f;
                }
                if (end.Contains("color"))
                    colors[1] = (Vector3)end["color"] / 255.0f;
            }
            else
            {
                isValueBySpace = false;
                foreach (int key in hashTable.Keys)
                {
                    float percent = key / 100.0f;


                    Hashtable date = (Hashtable)hashTable[key];
                    if (date.Contains("pos"))
                    {
                        vecsPos[2] = (Vector3)date["pos"];
                        OffsetXValueCurve.AddKey(percent, vecsPos[2].x);
                        OffsetYValueCurve.AddKey(percent, vecsPos[2].y);
                        OffsetZValueCurve.AddKey(percent, vecsPos[2].z);
                    }
                    if (date.Contains("scale"))
                    {
                        vecsScale[2] = (Vector3)date["scale"];
                        ScaleXValueCurve.AddKey(percent, vecsScale[2].x);
                        ScaleYValueCurve.AddKey(percent, vecsScale[2].y);
                        ScaleZValueCurve.AddKey(percent, vecsScale[2].z);
                    }
                    if (date.Contains("rotate"))
                    {
                        vecsRote[2] = (Vector3)date["rotate"];
                        RotateXValueCurve.AddKey(percent, vecsRote[2].x);
                        RotateYValueCurve.AddKey(percent, vecsRote[2].y);
                        RotateZValueCurve.AddKey(percent, vecsRote[2].z);
                    }
                    if (date.Contains("alpha"))
                    {
                        AlphaValueCurve.AddKey(percent, (float)date["alpha"]);
                    }
                    if (date.Contains("color"))
                    {
                        colors[2] = (Vector3)date["color"] / 255.0f;
                        ColorRValueCurve.AddKey(percent, colors[2].x);
                        ColorGValueCurve.AddKey(percent, colors[2].y);
                        ColorBValueCurve.AddKey(percent, colors[2].z);
                    }
                }
            }  
            
        }


        #endregion


    }
    #endregion




    public class MoveController : MonoBehaviour
    {
        public struct MoveNode
        {
            public float dwStartTime;
            public TargetObj objNode;
        }


        protected List<MoveNode> targetList = new List<MoveNode>();
        private List<MoveNode> deleteList = new List<MoveNode>();


        void Start()
        {
            
        }


        // Update is called once per frame
        void Update()
        {
            if (targetList == null)
            {
                return;
            }
            deleteList.Clear();
            foreach (MoveNode movenode in targetList)
            {
                if (movenode.dwStartTime <= Time.time)
                {
                    movenode.objNode.Update();
                    if (movenode.objNode.IsFinish == true)
                    {
                        deleteList.Add(movenode);
                    }
                }
            }


            foreach (MoveNode moveNode in deleteList)
            {
                targetList.Remove(moveNode);
            }
            deleteList.Clear();
        }


        //飞行效果
        public void DoFlyEffect(Transform target, Hashtable hashDate)
        {
            TargetObj objtarget = new TargetObj();
            int code = objtarget.AssighmentValue(target, hashDate);
            if (code != 0)
            {
                return;
            }


            MoveNode movenode = new MoveNode();
            movenode.objNode = objtarget;
            movenode.dwStartTime = Time.time;


            targetList.Add(movenode); 
        }
        
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值