Unity3d:实现自己的Dotween,C#扩展方法,插值旋转,插值移动

C#扩展方法

C#扩展方法第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。

public static class ExtendMethods
    {
    public static tween DoRotate(this Transform transform, Vector3 target, float time)
        {
            tween myTween = new tween("DoRotate", transform, target, time);
            Coroutine coroutine = DOTweenMgr.Instance.StartCoroutine(DOTweenMgr.Instance.YieldRotate(myTween));
            myTween.SetCoroutine(coroutine);
            return myTween;
        }
 }

以此实现
m_rotate.DoRotate(dir, 3);

tween信息

public class tween
    {
        public string tweenType;
        public int loops;
        public int currentLoop;

        public Transform transform;
        public Material material;
        public Vector3 originalPosition;
        public Vector3 originalRotation;
        public Vector3 originalScale;

        public Vector3 origin;
        public Vector3 target;

        public float time;
        public bool isPause;
        public bool autoKill;
        public Coroutine coroutine;

        public delegate void Callback();
        public Callback onComplete;
        public Callback onKill;
        public Callback onPause;

        public Quaternion m_rotation;
        public Quaternion m_tarRotation;
        public tween(string type, Transform trans, Vector3 tar, float ti,int ploops = 1)

把每次dotween要操作的tranform,tween类型(移动,旋转,缩放等),目标位置(角度),总共运动时间组装成tween返回

Mono单例类中开启协程做插值

旋转插值

  1. 在协程中插值运算,float f = myTween.time; f >= 0.0f; f -= Time.deltaTime,每帧递减运动时间
  2. myTween.transform.rotation = Quaternion.Lerp(myTween.m_rotation, myTween.m_tarRotation, 1.0f-f/myTween.time); tranfrom当前四元数 = 运动开始时 与 目标的差值 ,1.0f-f/myTween.time 的值在每帧越来越靠近 1,说明越来越向目标
        public static IEnumerator YieldRotate(this MonoBehaviour mono, tween myTween)
        {
            for (; myTween.currentLoop < myTween.loops; myTween.currentLoop++)
            {
                myTween.Reset();


                for (float f = myTween.time; f >= 0.0f; f -= Time.deltaTime)
                {
                    //changeEveryFrame(myTween, distance * Time.deltaTime);
                    myTween.transform.rotation = Quaternion.Lerp(myTween.m_rotation, myTween.m_tarRotation, 1.0f-f/myTween.time);
                    yield return null;
                    while (myTween.isPause == true)
                    {
                        yield return null;
                    }
                }
            }
            myTween.OnComplete();
        }

移动插值

//总长度/时间 = 每秒要移动的长度  ,然后每帧移动长度 = 每秒要移动的长度 *Time.deltaTime
        public static IEnumerator UniversalVector3Iter(this MonoBehaviour mono, tween myTween)
        {
            for (; myTween.currentLoop < myTween.loops; myTween.currentLoop++)
            {
                myTween.Reset();
                Vector3 distance = (myTween.target - myTween.origin) / myTween.time;
                for (float f = myTween.time; f >= 0.0f; f -= Time.deltaTime)
                {
                    myTween.transform.Translate(myTween, distance * Time.deltaTime);
                    yield return null;
                    while (myTween.isPause == true)
                    {
                        yield return null;
                    }
                }
            }
            myTween.OnComplete();
        }

源码

https://github.com/luoyikun/UnityForTest
DotweenDemo场景
Unity3d:实现自己的Dotween,C#扩展方法,插值旋转,插值移动_第1张图片

你可能感兴趣的:(Unity3d面试,Unity3d技术笔记,Unity3d,Dotween,c#扩展方法,插值旋转,插值移动)