Unity【NGUI】【UGUI】 动画效果实现,AnimationCurve曲线动画控制器,支持动画完成 回调

动画效果如下:


展示图1 如下:

展示图2 如下:

展示图3 如下:

功能: 如上图所示 移动,旋转,缩放,渐变透明  都可并行实现

只要脑洞够大,创意动画效果随你实现。

 

注:所有动画都是用曲线【AnimationCurve】调整实现

 

请教问题可添加QQ:1768556826

 

图1曲线:大致如下

图2曲线: 大致如下

 

参数说明:

DelayTime = 延迟播放时间
Time = 播放时间

每个动画类型有【两个选择类型】 None Normal  【两个参数】 FromTo;  

None = 关闭   Normal = 开启,From = 开始值  To = 目标值

 

实现步骤分两种,分别针对为 单个物体多个物体。

 

 

单个物体 实现步骤:(如上面 展示图3)

 

 

第一步:找个控件挂上 TweenContoller 脚本

第二步:勾选 自定义物体

选勾  【自定义物体】,参数  Play On Start = 运行时自动播放动画,Anim Game Obj = 目标物体

播放方式有两种

1: 选勾 Play On Start = 运行时自动播放动画

2:调用以下函数 播放动画:

 

最后一步:开启要进行的动画并且调整曲线

 

比如想实现边移动旋转,则在移动(Move)旋转(Rotate) 选择为 Normal,并且调整曲线即可(也可以使用默认曲线)

如下图:

然后运行,自动播放动画。

 

多个物体 实现步骤:(如上面 展示图1, 2)

 

第一步:找个控件挂上 TweenContoller 脚本

 

第二步:开启要进行的动画并且调整曲线

比如想实现边移动旋转,则在移动(Move)旋转(Rotate) 选择为 Normal,并且调整曲线即可(也可以使用默认曲线)

如下图:

 

最后一步:播放动画

.

 

整体代码如下:

 

一共有三个脚本文件:

TweenController(核心代码),TweenObjAttribute(物体属性脚本),TweenControllerEditor(编辑器显示脚本)

三个脚本都已上传

 

注:TweenControllerEditor文件 放到 Editor 文件目录下

 

TweenController.cs (核心代码)

/****************** UI 曲线动画控制器(动画完成时可回调函数) ****************************
 * 
 *   Leon Kim
 *   
 *   可用曲线 调整 动画表现方式,支持多个物体,多种动画混合 (比如 物体 移动位置的同时 播放旋转)
 *   
 *   
 *   单个物体时: (可无代码, 直接在TweenController组件上 选勾 自定义物体 并且拖拽即可)
 *   可用代码 控制开启
 *   StartTween()  (当勾选 自定义物体里面的 Play On Start时 运行时会调 StartTween()函数并开始播放)
 *   
 *   
 *   多个物体时:(以下都是代码接口)
 *   InitTweenType() 所有动画类型 还原成 初始开启模式
 *   OpenTweenType() 选择开启哪些动画类型 比如只开启 缩放和移动动画
 *   
 *   (1) StartMove()  
 *   (2) StartScale() 
 *   (3) StartRotate() 
 *   (4) StartAlpha()
 *   注:
 *   以上函数参数中 
 *   isOpenOnlyType = true 只播放当前动画(比如只移动或只旋转 不播放其他动画) 
 *   isOpenOnlyType = false 播放手动开启的动画 和 使用手动设置的值
 *   
 *   
 *   注:
 *   (0) 每个物体完成动画时 都会回调 Lua 函数 并且返回此物体
 *   (1) 挂此脚本的控件需 Anchor填充状态,
 *   (2) 从StartMove 传过来的物体 都在此控件层下(obj.SetParent(transform))
 *   (3) 此控件是动画控制器 本身不参与动画
 **/

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

    public enum TweenType
    {
        None,
        Normal,
    }
    public class TweenController : MonoBehaviour {

        private static TweenController _Instance = null;
        public static TweenController Instance
        {
            get
            {
                return _Instance;
            }
        }

        //存储 物体信息
        private List<TweenObjAttribute> objAttributeList = new List<TweenObjAttribute>();

        private Action<GameObject> callBackFunc;

        public float time = 1;   //动画进行时间
        public float delayTime = 0; //延迟时间

        //** 额外参数
        public bool isUseAdditionalParam = false;
        public bool playOnStart = false;
        public GameObject animGameObj;
        private RectTransform animGameObjRectTrans;

        private bool isTweening = false;
        private float updateTime = 0f;

        //** Position 动画相关
        public TweenType moveType = TweenType.None;
	    public AnimationCurve xCurve = AnimationCurve.Linear(0, 0, 1, 1);
	    public AnimationCurve yCurve = AnimationCurve.Linear(0, 0, 1, 1);
        public Vector3 fromPos;
        public Vector3 toPos;

		//** 偏移 动画相关
		public TweenType offsetType = TweenType.None;
		public AnimationCurve offsetCurve = AnimationCurve.Linear(0, 0, 1, 1);
		public float offset;

        //** Scale 动画相关
	    public TweenType scaleType = TweenType.None;
	    public AnimationCurve scaleCurve = AnimationCurve.Linear(0, 0, 1, 1);
        public Vector3 fromScale = Vector3.one;
	    public Vector3 toScale = Vector3.one;

        //** Rotate 动画相关
        public TweenType rotateType = TweenType.None;
	    public AnimationCurve rotateCurve = AnimationCurve.Linear(0, 0, 1, 1);
        public Vector3 fromRotate = Vector3.zero;
        public Vector3 toRotate = Vector3.zero;

        //** Alpha 动画相关
        public TweenType alphaType = TweenType.None;
	    public AnimationCurve alphaCurve = AnimationCurve.Linear(0, 0, 1, 1);
        public float fromAlpha;
        public float toAlpha;



        private List<TweenType> beginTypeList = new List<TweenType>();

		private bool isAwake = false;
		private void Awake()
		{
			isAwake = true;
            _Instance = this;
        }


        private void Start()
        {
            //初始化用
            beginTypeList.Add(moveType);
            beginTypeList.Add(scaleType);
            beginTypeList.Add(rotateType);
            beginTypeList.Add(alphaType);

            if (playOnStart)
            {
                StartTween();
            }

        }

        //还原成默认 动画类型
        public void InitTweenType()
        {
            moveType = beginTypeList[0];
            scaleType = beginTypeList[1];
            rotateType = beginTypeList[2];
            alphaType = beginTypeList[3];
        }

        //选择性 动画类型开启方式 (移动,缩放,旋转,Alpha)
        public void OpenTweenType(bool isOpenMoveType, bool isOpenScaleType, bool isOpenRotateType, bool isOpenAlphaType)
        {
            moveType = isOpenMoveType ? TweenType.Normal : TweenType.None;
            scaleType = isOpenScaleType ? TweenType.Normal : TweenType.None;
            rotateType = isOpenRotateType ? TweenType.Normal : TweenType.None;
            alphaType = isOpenAlphaType ? TweenType.Normal : TweenType.None;
        }

        //普通 开始动画 (用于 自定义物体)
        public void StartTween()
        {
            StartTween(null);
        }
        //开始 带回调的 动画  (用于 自定义物体)
        public void StartTween(Action<GameObject> callBackFunc)
        {
			if (!isAwake && callBackFunc != null)
            {
                Debug.LogError(string.Format("This GameObject({0}) is not activated", this.gameObject.name));
            }

            if (!isUseAdditionalParam) return;

            if (animGameObj == null) return;

            if (moveType != TweenType.None)
            {
                animGameObj.transform.GetComponent<RectTransform>().anchoredPosition = fromPos;
            }
            if (scaleType != TweenType.None)
            {
                animGameObj.transform.localScale = fromScale;
            }
            if (rotateType != TweenType.None)
            {
                animGameObj.transform.localRotation = Quaternion.Euler(fromRotate);
            }
            if (alphaType != TweenType.None)
            {
                CanvasGroup g = animGameObj.GetComponent<CanvasGroup>();
                if(g == null)
                {
                    g = animGameObj.AddComponent<CanvasGroup>();
                }
                g.alpha = fromAlpha;
            }

            animGameObjRectTrans = animGameObj.GetComponent<RectTransform>();

            updateTime = 0;
            isTweening = true;
        }

        //-------------------------------------------------------------->>>  移动动画 接口  <<<--------------------------------------------------------------------------
        //isOpenOnlyType == true 仅开启移动动画 其他动画关闭 
        //isOpenOnlyType == false 用手动设置的动画开启 和 除Position外 用手动设置的值

        //参数 (物体,开始Pos,目标Pos,是否仅开启移动动画)
        public void StartMove(GameObject obj, Vector3 fromPos, Vector3 toPos, bool isOpenOnlyType)
        {
            StartMove(obj, fromPos, toPos, isOpenOnlyType, null);
        }
        //参数 (物体,开始Pos,目标Pos,是否仅开启移动动画,回调函数)
        public void StartMove(GameObject obj, Vector3 fromPos, Vector3 toPos, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
            StartMove(obj, fromPos, toPos, time, delayTime, isOpenOnlyType, callBackFunc);
        }
        //参数 (物体,开始Pos,目标Pos, 持续时间,延迟时间,是否仅开启移动动画,回调函数)
        public void StartMove(GameObject obj, Vector3 fromPos, Vector3 toPos, float timeLength, float delayTime, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
            StartMove(obj, fromPos, toPos, timeLength, delayTime, isOpenOnlyType, false, false, callBackFunc);
        }
		public void StartMove(GameObject obj, Vector3 fromPos, Vector3 toPos, float timeLength, float delayTime, bool isOpenOnlyType, bool isCounterX, bool isCounterY, Action<GameObject> callBackFunc)
		{
			StartMove(obj, fromPos, toPos, timeLength, delayTime, isOpenOnlyType, false, false, callBackFunc, 0);
		}
        //参数 (物体,开始Pos,目标Pos, 持续时间,延迟时间,是否仅开启移动动画,x曲线是否反轨迹运动,y曲线是否反轨迹运动,回调函)
		public void StartMove(GameObject obj, Vector3 fromPos, Vector3 toPos, float timeLength, float delayTime, bool isOpenOnlyType, bool isCounterX, bool isCounterY, Action<GameObject> callBackFunc, float offset)
        {
			if (!isAwake)
            {
                Debug.LogError(string.Format("This GameObject({0}) is not activated", this.gameObject.name));
            }

            //obj.transform.SetParent(transform);

            TweenObjAttribute attribute = isOpenOnlyType ? new TweenObjAttribute(1) : new TweenObjAttribute(moveType, scaleType, rotateType, alphaType, this);

            attribute.Obj = obj;
            //attribute.RectTrans = obj.GetComponent<RectTransform>();
            attribute.FromPos = fromPos;
            attribute.ToPos = toPos;
            attribute.UpdateTime = 0;
            attribute.Time = timeLength;
            attribute.DelayTime = delayTime;
            //obj.transform.localPosition = fromPos;
            attribute.IsCounterX = isCounterX;
            attribute.IsCounterY = isCounterY;
			attribute.Offset = offset;
            attribute.CallBackFunc = callBackFunc;

            objAttributeList.Add(attribute);

            attribute.IsTweening = true;
        }

		//支持偏移的动画 参数 (物体,开始Pos,目标Pos, 持续时间,延迟时间,是否仅开启移动动画,偏移值,回调函数)
		public void StartOffsetMove(GameObject obj, Vector3 fromPos, Vector3 toPos, float timeLength, float delayTime, float offset,bool isOpenOnlyType, Action<GameObject> callBackFunc)
		{
			StartMove(obj, fromPos, toPos, timeLength, delayTime, isOpenOnlyType, false, false, callBackFunc, offset);
		}
        //-------------------------------------------------------------->>>  缩放动画 接口  <<<--------------------------------------------------------------------------
        //isOpenOnlyType == true 仅开启移动动画 其他动画关闭 
        //isOpenOnlyType == false 用手动设置的动画开启 和 除Scale外 用手动设置的值

        //参数 (物体,开始Scale,目标Scale,是否仅开启 Scale 动画)
        public void StartScale(GameObject obj, Vector3 fromScale, Vector3 toScale, bool isOpenOnlyType)
        {
            StartScale(obj, fromScale, toScale, isOpenOnlyType, null);
        }
        //参数 (物体,开始Scale,目标Scale,是否仅开启 Scale 动画, 回调函数)
        public void StartScale(GameObject obj, Vector3 fromScale, Vector3 toScale, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
            StartScale(obj, fromScale, toScale, time, delayTime, isOpenOnlyType, callBackFunc);
        }
        //参数 (物体,开始Scale,目标Scale, 持续时间,延迟时间,是否仅开启 Scale 动画, 回调函数)
        public void StartScale(GameObject obj, Vector3 fromScale, Vector3 toScale, float timeLength, float delayTime, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
			if (!isAwake)
            {
                Debug.LogError(string.Format("This GameObject({0}) is not activated", this.gameObject.name));
            }

            //obj.transform.SetParent(transform);

            TweenObjAttribute attribute = isOpenOnlyType ? new TweenObjAttribute(2) : new TweenObjAttribute(moveType, scaleType, rotateType, alphaType, this);

            attribute.Obj = obj;

            attribute.FromScale = fromScale;
            attribute.ToScale = toScale;

            attribute.UpdateTime = 0;
            attribute.Time = timeLength;
            attribute.DelayTime = delayTime;
            //attribute.Obj.transform.GetComponent<RectTransform>().anchoredPosition = fromPos;
            attribute.CallBackFunc = callBackFunc;

            objAttributeList.Add(attribute);

            attribute.IsTweening = true;
        }

        //-------------------------------------------------------------->>> 旋转动画 接口  <<<--------------------------------------------------------------------------
        //isOpenOnlyType == true 仅开启移动动画 其他动画关闭 
        //isOpenOnlyType == false 用手动设置的动画开启 和 除Rotate外 用手动设置的值

        //参数 (物体,开始Rotate,目标Rotate,是否仅开启 Rotate 动画)
        public void StartRotate(GameObject obj, Vector3 fromRotate, Vector3 toRotate, bool isOpenOnlyType)
        {
            StartRotate(obj, fromRotate, toRotate, isOpenOnlyType, null);
        }
        //参数 (物体,开始Rotate,目标Rotate,是否仅开启 Rotate 动画, 回调函数)
        public void StartRotate(GameObject obj, Vector3 fromRotate, Vector3 toRotate, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
            StartRotate(obj, fromRotate, toRotate, time, delayTime, isOpenOnlyType, callBackFunc);
        }
        //参数 (物体,开始Rotate,目标Rotate, 持续时间,延迟时间,是否仅开启 Rotate 动画, 回调函数)
        public void StartRotate(GameObject obj, Vector3 fromRotate, Vector3 toRotate, float timeLength, float delayTime, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
			if (!isAwake)
            {
                Debug.LogError(string.Format("This GameObject({0}) is not activated", this.gameObject.name));
            }

            //obj.transform.SetParent(transform);

            TweenObjAttribute attribute = isOpenOnlyType ? new TweenObjAttribute(3) : new TweenObjAttribute(moveType, scaleType, rotateType, alphaType, this);

            attribute.Obj = obj;

            attribute.FromRotate = fromRotate;
            attribute.ToRotate = toRotate;

            attribute.UpdateTime = 0;
            attribute.Time = timeLength;
            attribute.DelayTime = delayTime;
            attribute.Obj.transform.GetComponent<RectTransform>().anchoredPosition = fromPos;
            attribute.CallBackFunc = callBackFunc;

            objAttributeList.Add(attribute);

            attribute.IsTweening = true;
        }

        //-------------------------------------------------------------->>>  Alpha动画 接口  <<<--------------------------------------------------------------------------
        //isOpenOnlyType == true 仅开启移动动画 其他动画关闭 
        //isOpenOnlyType == false 用手动设置的动画开启 和 除Alpha外 用手动设置的值

        //参数 (物体,开始Alpha,目标alpha,是否仅开启 Alpha 动画)
        public void StartAlpha(GameObject obj, float fromAlpha, float toAlpha, bool isOpenOnlyType)
        {
            StartAlpha(obj, fromAlpha, toAlpha, isOpenOnlyType, null);
        }
        //参数 (物体,开始Alpha,目标alpha,是否仅开启 Alpha 动画, 回调函数)
        public void StartAlpha(GameObject obj, float fromAlpha, float toAlpha, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
            StartAlpha(obj, fromAlpha, toAlpha, time, delayTime, isOpenOnlyType, callBackFunc);
        }
        //参数 (物体,开始Alpha,目标alpha, 持续时间,延迟时间,是否仅开启 Alpha 动画, 回调函数)
        public void StartAlpha(GameObject obj, float fromAlpha, float toAlpha, float timeLength, float delayTime, bool isOpenOnlyType, Action<GameObject> callBackFunc)
        {
			if (!isAwake)
            {
                Debug.LogError(string.Format("This GameObject({0}) is not activated", this.gameObject.name));
            }

            //obj.transform.SetParent(transform);

            TweenObjAttribute attribute = isOpenOnlyType ? new TweenObjAttribute(4) : new TweenObjAttribute(moveType, scaleType, rotateType, alphaType, this);

            attribute.Obj = obj;

            attribute.FromAlpha = fromAlpha;
            attribute.ToAlpha = toAlpha;

            attribute.UpdateTime = 0;
            attribute.Time = timeLength;
            attribute.DelayTime = delayTime;
            attribute.Obj.transform.GetComponent<RectTransform>().anchoredPosition = fromPos;
            attribute.CallBackFunc = callBackFunc;

            objAttributeList.Add(attribute);

            attribute.IsTweening = true;
        }

		public void ClearTween()
		{
			DisposeAll ();
			objAttributeList.Clear ();
		}

        private void Update () {
            //** 自定义物体 动画
            if (isTweening && animGameObj)
            {
                updateTime += Time.deltaTime;

                //判断 是否动画完成
                if (updateTime - delayTime > time)
                {
                    StopNormalTween();
                }
                else if(updateTime - delayTime >= 0)
                {
                    float t = (updateTime - delayTime) / time;

                    UpdateMove(moveType, animGameObj, fromPos, toPos, t);
                    UpdateScale(scaleType, animGameObj, fromScale, toScale, t);
                    UpdateRotate(rotateType, animGameObj, fromRotate, toRotate, t);
                    UpdateFade(alphaType, animGameObj, fromAlpha, toAlpha, t);
                }
            }

            //** 代码里指定的物体 动画
            if (objAttributeList.Count <= 0) return;

            for(int i = 0; i < objAttributeList.Count; i++)
            {
                TweenObjAttribute objAttribute = objAttributeList[i];
                if (!objAttribute.IsTweening) continue;

                objAttribute.UpdateTime += Time.deltaTime;

                //判断 是否动画完成
                if (objAttribute.UpdateTime - objAttribute.DelayTime > objAttribute.Time)
                {
                    StopTween(objAttribute);
                }
                else if (objAttribute.UpdateTime - objAttribute.DelayTime >= 0)
                {
					if (!objAttribute.Obj.activeSelf)
						objAttribute.Obj.SetActive (true);

                    float t = (objAttribute.UpdateTime - objAttribute.DelayTime) / objAttribute.Time;

					UpdateMove(objAttribute.MoveType, objAttribute.Obj, objAttribute.FromPos, objAttribute.ToPos, t, objAttribute.IsCounterX, objAttribute.IsCounterY, objAttribute.Offset);
                    UpdateScale(objAttribute.ScaleType, objAttribute.Obj, objAttribute.FromScale, objAttribute.ToScale, t);
                    UpdateRotate(objAttribute.RotateType, objAttribute.Obj, objAttribute.FromRotate, objAttribute.ToRotate, t);
                    UpdateFade(objAttribute.AlphaType, objAttribute.Obj, objAttribute.FromAlpha, objAttribute.ToAlpha, t);
                }
            }
	    }

        //移动(Move)动画
		private void UpdateMove(TweenType type, GameObject obj, Vector3 fromPos,Vector3 toPos, float t, bool isCounterX = false, bool isCounterY = false, float offset = 0)
	    {
            if (type == TweenType.None)
                return;

		    Vector3 move = toPos - fromPos;

            float xVar = xCurve.Evaluate(t);
            float yVar = yCurve.Evaluate(t);
            float val = t / time;
            move.x *= !isCounterX ? val - (val - xVar) : val + (val - xVar);
            move.y *= !isCounterY ? val - (val - yVar) : val + (val - yVar);

			//偏移值
			float offsetVal = offsetCurve.Evaluate (t);
			float oVal = offset * offsetVal;

			float a = Vector3.Angle (move, Vector3.left) - 90;
			float offsetY = oVal * Mathf.Sin (a * Mathf.Deg2Rad);
			float offsetX = oVal * Mathf.Cos (a * Mathf.Deg2Rad);

            obj.transform.localPosition = fromPos + move + new Vector3(-offsetX, offsetY, 0);
	    }
        //缩放(Scale)动画
        private void UpdateScale(TweenType type, GameObject obj, Vector3 fromScale, Vector3 toScale, float t)
        {
            if (type == TweenType.None)
                return;

            float val = scaleCurve.Evaluate(t);
            Vector3 s = fromScale * (1 - val) + toScale * val;
            obj.transform.localScale = s;
        }
        //旋转(Rotate)动画
        private void UpdateRotate(TweenType type, GameObject obj, Vector3 fromRotate, Vector3 toRotate, float t)
        {
            if (type == TweenType.None)
                return;

            float val = rotateCurve.Evaluate(t);
            Vector3 s = fromRotate * (1 - val) + toRotate * val;
            obj.transform.localRotation = Quaternion.Euler(s);
        }

        //透明(Alpha)动画
        Dictionary<GameObject, AnimatedAlpha> canvasGroups = new Dictionary<GameObject, AnimatedAlpha>(); 
        private void UpdateFade(TweenType type, GameObject obj, float fromAlpha, float toAlpha, float t)
        {
            if (type == TweenType.None)
                return;

        AnimatedAlpha g = null;
            if (!canvasGroups.ContainsKey(obj))
            {
                g = obj.GetComponent<AnimatedAlpha>();
                canvasGroups[obj] = g;
            }
            else
            {
                g = canvasGroups[obj];
            }

            if (g == null)
                return;

            float val = alphaCurve.Evaluate(t);
            g.alpha = fromAlpha * (1 - val) + toAlpha * val;
        }


        private void StopNormalTween()
        {
            if (moveType != TweenType.None)
            {
                animGameObj.transform.localPosition= toPos;
            }
            if (scaleType != TweenType.None)
            {
                //animGameObj.transform.localScale = toScale;
            }
            if (rotateType != TweenType.None)
            {
                animGameObj.transform.localRotation = Quaternion.Euler(toRotate);
            }
            if (alphaType != TweenType.None)
            {
            AnimatedAlpha g = animGameObj.GetComponent<AnimatedAlpha>();
                if (g != null)
                {
                    g.alpha = toAlpha;
                }
            }
            
            updateTime = 0;
            isTweening = false;
            
            if (callBackFunc != null)
            {
                callBackFunc(animGameObj);
            }
        }

        private void StopTween(TweenObjAttribute objManager)
        {
			if (objManager.Obj == null)
				return;
			
            if (objManager.MoveType != TweenType.None)
            {
                objManager.Obj.transform.localPosition = objManager.ToPos;
            }
            if (objManager.ScaleType != TweenType.None)
            {
                objManager.Obj.transform.localScale = toScale;
            }
            if (objManager.RotateType != TweenType.None)
            {
                objManager.Obj.transform.localRotation = Quaternion.Euler(toRotate);
            }
            if (objManager.AlphaType != TweenType.None)
            {
                AnimatedAlpha g = objManager.Obj.GetComponent<AnimatedAlpha>();
                if (g != null)
                {
                    g.alpha = objManager.ToAlpha;
                }
            }
            objManager.IsTweening = false;
            objManager.UpdateTime = 0;

            if (objManager.CallBackFunc != null)
            {
                objManager.CallBackFunc(objManager.Obj);
            }

            objAttributeList.Remove(objManager);
        }

        private void OnDestroy()
        {
			DisposeAll ();
        }

		private void Dispose()
		{
			for(int i = 0,length = objAttributeList.Count; i < length; i++)
			{
				objAttributeList[i].Dispose();
				objAttributeList [i].Obj = null;
			}
			objAttributeList.Clear ();
		}

		public void DisposeAll()
        {
            Dispose();
        }
    }

TweenObjAttribute.cs(物体属性脚本)

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

    public class TweenObjAttribute
    {
        private GameObject obj;     //物体
        private RectTransform rectTrans;

        private Vector3 fromPos;    //初始 Vector3 值 
        private Vector3 toPos;      //目标 Vector3 值

        private Vector3 fromScale;    //初始 Vector3 值 
        private Vector3 toScale;      //目标 Vector3 值

        private Vector3 fromRotate;    //初始 Vector3 值 
        private Vector3 toRotate;      //目标 Vector3 值

        private float fromAlpha = 0; //初始Alpha值
        private float toAlpha = 0;  //目标Alpha值

        private float updateTime = 0;  //实时更新的时间
        private bool isTweening = false;    //是否开启动画
        private float time = 1;  //时间长度
        private float delayTime = 0;  //延迟时间
        private bool isCounterX = false; //是否反曲线运动
        private bool isCounterY = false; //是否反曲线运动
		private float offset = 0; //偏移值

        private TweenType moveType = TweenType.None;
        private TweenType scaleType = TweenType.None;
        private TweenType rotateType = TweenType.None;
        private TweenType alphaType = TweenType.None;

        public Action<GameObject> CallBackFunc;

        public TweenObjAttribute()
        {

        }
        public TweenObjAttribute(TweenType moveType, TweenType scaleType, TweenType rotateType, TweenType alphaType, TweenController tweenController)
        {
            this.moveType = moveType;
            this.scaleType = scaleType;
            this.rotateType = rotateType;
            this.alphaType = alphaType;

            fromPos = tweenController.fromPos;
            toPos = tweenController.toPos;

            fromScale = tweenController.fromScale;
            toScale = tweenController.toScale;

            fromRotate = tweenController.fromRotate;
            toRotate = tweenController.toRotate;

            fromAlpha = tweenController.fromAlpha;
            toAlpha = tweenController.toAlpha;
        }

        //仅开启 某类型动画 (1 = 移动,2 = 缩放,3 = 旋转,4 = Alpha, 其他 = 默认)
        public TweenObjAttribute(int type)
        {
            switch (type)
            {
                case 1:
                    moveType = TweenType.Normal;
                    scaleType = TweenType.None;
                    rotateType = TweenType.None;
                    alphaType = TweenType.None;
                    break;
                case 2:
                    moveType = TweenType.None;
                    scaleType = TweenType.Normal;
                    rotateType = TweenType.None;
                    alphaType = TweenType.None;
                    break;
                case 3:
                    moveType = TweenType.None;
                    scaleType = TweenType.None;
                    rotateType = TweenType.Normal;
                    alphaType = TweenType.None;
                    break;
                case 4:
                    moveType = TweenType.None;
                    scaleType = TweenType.None;
                    rotateType = TweenType.None;
                    alphaType = TweenType.Normal;
                    break;
                default:
                    break;
            }
        }

        public GameObject Obj
        {
            get
            {
                return obj;
            }

            set
            {
                obj = value;
            }
        }

        public float UpdateTime
        {
            get
            {
                return updateTime;
            }

            set
            {
                updateTime = value;
            }
        }

        public bool IsTweening
        {
            get
            {
                return isTweening;
            }

            set
            {
                isTweening = value;
            }
        }

        public float Time
        {
            get
            {
                return time;
            }

            set
            {
                time = value;
            }
        }

        public float DelayTime
        {
            get
            {
                return delayTime;
            }

            set
            {
                delayTime = value;
            }
        }

        public bool IsCounterX
        {
            get
            {
                return isCounterX;
            }

            set
            {
                isCounterX = value;
            }
        }

        public bool IsCounterY
        {
            get
            {
                return isCounterY;
            }

            set
            {
                isCounterY = value;
            }
        }

        public float FromAlpha
        {
            get
            {
                return fromAlpha;
            }

            set
            {
                fromAlpha = value;
            }
        }

        public float ToAlpha
        {
            get
            {
                return toAlpha;
            }

            set
            {
                toAlpha = value;
            }
        }

        public TweenType MoveType
        {
            get
            {
                return moveType;
            }

            set
            {
                moveType = value;
            }
        }

        public TweenType ScaleType
        {
            get
            {
                return scaleType;
            }

            set
            {
                scaleType = value;
            }
        }

        public TweenType RotateType
        {
            get
            {
                return rotateType;
            }

            set
            {
                rotateType = value;
            }
        }

        public TweenType AlphaType
        {
            get
            {
                return alphaType;
            }

            set
            {
                alphaType = value;
            }
        }

        public Vector3 FromPos
        {
            get
            {
                return fromPos;
            }

            set
            {
                fromPos = value;
            }
        }

        public Vector3 ToPos
        {
            get
            {
                return toPos;
            }

            set
            {
                toPos = value;
            }
        }

		public float Offset
		{
			get
			{
				return offset;
			}

			set
			{
				offset = value;
			}
		}

        public Vector3 FromScale
        {
            get
            {
                return fromScale;
            }

            set
            {
                fromScale = value;
            }
        }

        public Vector3 ToScale
        {
            get
            {
                return toScale;
            }

            set
            {
                toScale = value;
            }
        }

        public Vector3 FromRotate
        {
            get
            {
                return fromRotate;
            }

            set
            {
                fromRotate = value;
            }
        }

        public Vector3 ToRotate
        {
            get
            {
                return toRotate;
            }

            set
            {
                toRotate = value;
            }
        }

        public RectTransform RectTrans
        {
            get
            {
                return rectTrans;
            }

            set
            {
                rectTrans = value;
            }
        }

        public void Dispose()
        {

        }
    }

 

TweenControllerEditor.cs(编辑器显示脚本)

/*
 * Author Leon kim
 * 
*/

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;

    [CustomEditor(typeof(TweenController), true)]
    public class TweenControllerEditor : Editor
    {
        SerializedProperty delayTime;
        SerializedProperty time;

        SerializedProperty isUseAddtionalParam;
        SerializedProperty playOnStart;
        SerializedProperty animGameObj;

        SerializedProperty xCurve;
        SerializedProperty yCurve;
        SerializedProperty fromPos;
        SerializedProperty toPos;

		SerializedProperty offsetCurve;
		SerializedProperty offset;

        SerializedProperty scaleCurve;
        SerializedProperty fromScale;
        SerializedProperty toScale;

        SerializedProperty rotateCurve;
        SerializedProperty fromRotate;
        SerializedProperty toRotate;

        SerializedProperty alphaCurve;
        SerializedProperty fromAlpha;
        SerializedProperty toAlpha;

        protected void OnEnable()
        {
            delayTime = serializedObject.FindProperty("delayTime");
            time = serializedObject.FindProperty("time");

            xCurve = serializedObject.FindProperty("xCurve");
            yCurve = serializedObject.FindProperty("yCurve");
            fromPos = serializedObject.FindProperty("fromPos");
            toPos = serializedObject.FindProperty("toPos");

			offsetCurve = serializedObject.FindProperty ("offsetCurve");
			offset = serializedObject.FindProperty ("offset");

            scaleCurve = serializedObject.FindProperty("scaleCurve");
            fromScale = serializedObject.FindProperty("fromScale");
            toScale = serializedObject.FindProperty("toScale");

            rotateCurve = serializedObject.FindProperty("rotateCurve");
            fromRotate = serializedObject.FindProperty("fromRotate");
            toRotate = serializedObject.FindProperty("toRotate");

            alphaCurve = serializedObject.FindProperty("alphaCurve");
            fromAlpha = serializedObject.FindProperty("fromAlpha");
            toAlpha = serializedObject.FindProperty("toAlpha");

            playOnStart = serializedObject.FindProperty("playOnStart");
            animGameObj = serializedObject.FindProperty("animGameObj");
        }

        public override void OnInspectorGUI()
        {
            TweenController tw = target as TweenController;

            //serializedObject.Update();
            EditorGUILayout.PropertyField(delayTime);
            EditorGUILayout.PropertyField(time);

            EditorGUI.indentLevel = 0;
            tw.isUseAdditionalParam = EditorGUILayout.ToggleLeft("自定义物体", tw.isUseAdditionalParam);
            if (tw.isUseAdditionalParam)
            {
                EditorGUI.indentLevel = 1;
                EditorGUILayout.PropertyField(playOnStart);
                EditorGUILayout.PropertyField(animGameObj);
            }

            EditorGUI.indentLevel = 0;
            tw.moveType = (TweenType)EditorGUILayout.EnumPopup("移动 (Move)", (System.Enum)tw.moveType);
            if(tw.moveType != TweenType.None)
            {
                EditorGUI.indentLevel = 1;
                EditorGUILayout.PropertyField(xCurve);
                EditorGUILayout.PropertyField(yCurve);

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PropertyField(fromPos);
                if (GUILayout.Button("reset"))
                {
                    try
                    {
                        tw.fromPos = tw.animGameObj.transform.GetComponent<RectTransform>().anchoredPosition;
                    }
                    catch
                    {
                        throw new System.Exception("此按钮仅 自定义物体时 可用, 若需自定义请指定物体到 Anim Game Obj");
                    }
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PropertyField(toPos);
                if (GUILayout.Button("reset"))
                {
                    try
                    {
                        tw.toPos = tw.animGameObj.transform.GetComponent<RectTransform>().anchoredPosition;
                    }
                    catch
                    {
                        throw new System.Exception("此按钮仅 自定义物体时 可用, 若需自定义请指定物体到 Anim Game Obj");
                    }
            	}
                EditorGUILayout.EndHorizontal();

				tw.offsetType = (TweenType)EditorGUILayout.EnumPopup ("偏移 (offset)", (System.Enum)tw.offsetType);
				if (tw.offsetType != TweenType.None) {
					EditorGUILayout.PropertyField(offsetCurve);
					EditorGUILayout.BeginHorizontal();
					EditorGUILayout.PropertyField(offset);
					EditorGUILayout.EndHorizontal ();
				}
            }

            EditorGUI.indentLevel = 0;
            tw.scaleType = (TweenType)EditorGUILayout.EnumPopup("缩放 (Scale)", (System.Enum)tw.scaleType);
            if(tw.scaleType != TweenType.None)
            {
                EditorGUI.indentLevel = 1;
                EditorGUILayout.PropertyField(scaleCurve);
                EditorGUILayout.PropertyField(fromScale);
                EditorGUILayout.PropertyField(toScale);
                
            }
            EditorGUI.indentLevel = 0;
            tw.rotateType = (TweenType)EditorGUILayout.EnumPopup("旋转 (Rotate)", (System.Enum)tw.rotateType);
            if(tw.rotateType != TweenType.None)
            {
                EditorGUI.indentLevel= 1;
                EditorGUILayout.PropertyField(rotateCurve);
                EditorGUILayout.PropertyField(fromRotate);
                EditorGUILayout.PropertyField(toRotate);
            }
            EditorGUI.indentLevel = 0;
            tw.alphaType = (TweenType)EditorGUILayout.EnumPopup("透明 (Alpha)", (System.Enum)tw.alphaType);
            if (tw.alphaType != TweenType.None)
            {
                EditorGUI.indentLevel = 1;
                EditorGUILayout.PropertyField(alphaCurve);
                EditorGUILayout.PropertyField(fromAlpha);
                EditorGUILayout.PropertyField(toAlpha);
            }
            
            serializedObject.ApplyModifiedProperties();
        }

    }

 

 

 

 

 

 

 

 

 

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Unity3D中,可以通过以下几种方式实现动画控制器播放完成回调: 1. 使用AnimationEvent Unity3D中的AnimationEvent可以在动画播放过程中插入自定义事件,可以在动画播放完成时触发回调函数。具体实现步骤如下: - 在动画控制器中选中要添加事件的动画片段,打开Animation选项卡。 - 点击Add Event按钮,在动画片段中添加事件点。 - 选择添加事件点后,在Inspector窗口中可以设置事件的参数,包括事件函数名、参数等。 - 在脚本中编写事件回调函数。 示例代码: ```csharp using UnityEngine; using System.Collections; public class AnimationCallback : MonoBehaviour { public void OnAnimationFinished() { Debug.Log("Animation finished"); } } ``` 2. 使用AnimationClip.isReadyToPlay Unity3D中的AnimationClip类提供了isReadyToPlay属性,可以检测动画片段是否已准备好播放。可以在动画片段准备好播放时触发回调函数。具体实现步骤如下: - 在脚本中获取动画片段的引用。 - 在Update函数中检测动画片段是否准备好播放,如果准备好则触发回调函数。 示例代码: ```csharp using UnityEngine; using System.Collections; public class AnimationCallback : MonoBehaviour { public AnimationClip animClip; void Update() { if (animClip.isReadyToPlay && !animClip.isPlaying) { OnAnimationFinished(); } } public void OnAnimationFinished() { Debug.Log("Animation finished"); } } ``` 3. 使用AnimationEventTrigger Unity3D中的AnimationEventTrigger组件可以在动画播放过程中自动触发回调函数。具体实现步骤如下: - 在脚本中编写事件回调函数。 - 将脚本挂载到包含AnimationEventTrigger组件的游戏对象上。 - 在AnimationEventTrigger组件中添加事件,选择要触发的回调函数。 示例代码: ```csharp using UnityEngine; using System.Collections; public class AnimationCallback : MonoBehaviour { public void OnAnimationFinished() { Debug.Log("Animation finished"); } } ``` 注意:使用AnimationEventTrigger需要Unity版本在2019.1以上。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙笑~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值