unity作业——简单dotween的制作
来源:互联网 发布:北京java培训机构学费 编辑:程序博客网 时间:2024/06/06 14:01
这次作业,老师让我们仿制一个简单的dotween,扩展一下transform中的方法,在这里我扩展了三个方法,使得例如调用transform.DoTranslate, transform.DoRotate,Transform.DoScale分别实现物体的平移,旋转和大小的改变。这里老师上课的网站上重点介绍了要实现这几个功能,需要用到协程,动态方法和lambda表达式。lambda表达式在这次作业中我还没有用到,但是协程和动态方法这次是必须要用的。首先我来谈一下我对协程的理解。
协程,可以说是伪线程。即它看上去像线程,但它的中断是显式的,直到指定的事件发生,由ReActor调度程序从当前断点继续执行。 也即是说当我们一般在执行函数调用时,函数会在一帧的时间内完成,若我们不想函数在一帧的时间内完成,而是分步执行,每次只执行一部分,下次执行时由上次执行的最后一句的下一句开始,这时我们就要用到协程。协程定义的方式为:IEnumerator+函数名(参数列表),同时要在返回语句前加上关键字yield,下面我们来看一个具体例子,就是潘老师的网站上所写的。
IEnumerator Fade() { for (float f = 1f; f >= 0; f -= 0.1f) { Color c = renderer.material.color; c.a = f; renderer.material.color = c; yield return null; }}
上述程序表示每当启动Fade启动后就会获得cpu时间,知道yield中断语句的执行。return null表示下次update事件发生时,自动从下一条语句执行。上述函数是一个渐变的改
变颜色的函数,可以助我们更好的实现颜色的变化。
启动协程。
void Update() { if (Input.GetKeyDown("f")) { StartCoroutine("Fade"); }}以上工作就完成了协程的启动,因为这次我们的任务是要求在一定的时间内实现对物体Transform属性的改变,因此必须要用到协程。下面是我对扩展方法的理解。扩展方法则是在现有的类中增加方法,无需继承就可以改写类,这次我们就需要在Transform类中增加三个方法。扩展方法的格式为:public static 返回类型 函数名(this Typeanme class, 参数){}这样就扩展出了一个方法,以下引用一段微软官方的对扩展方法的解释。扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。下面是一段老师网站的代码,帮助我们重点理解一下扩展方法。public static class extend_method_test{ //This is Extened Method, The first parameter beging with (this Type name, args) public static bool NextBool(this System.Random random) { return random.NextDouble() > 0.5; }}public class NewBehaviourScript : MonoBehaviour { // Use this for initialization void Start () { System.Random rand = new System.Random(); print (rand.NextBool ()); } // Update is called once per frame void Update () { }}这里就在系统类System.Random中增加了一个新的方法NextBool,即返回下一个大于0.5的随机数。在有了上述准备知识后,这次作业就比较容易理解了,首先是dotween类的编写,我们这里实现第一个效果DoRotate,使得物体能够在指定的时间内平移一定角度。dotween对应的是相应动作的协程,和动作对应的协程一一对应,里面存储了关于这个动作的各个信息,其中包括要为其设置协程。还有两个比较重要的变量,isPause和autoKill,autoKill代表的是对应的动作结束后是否自动销毁,而isPause则意味着显示决定动作是否暂停和继续。public class dotween{public string name; //对应的动作名public Coroutine coroutine = null; // 要添加的协程public Transform trans = null;public float time;public bool isPause = false;public bool autoKill = true;public Vector3 target;public delegate void OnComplete(); // 相应的委托public OnComplete onComplete = null;public dotween(string s, Transform t, Vector3 v, float ti, Coroutine c) {name = s;trans = t;target = v;time = ti;//Dotween.getInstance ().Add (this);}//设置协程public void setCoroutine(Coroutine c) {coroutine = c;}//杀死协程,此时只是第一步,我们先求实现一个动作,不添加工厂管理这些动作,将与工厂有关的代码先注释掉public void Kill() {MonoBehaviour mono = trans.GetComponent<MonoBehaviour> ();mono.StopCoroutine (coroutine);//Dotween.getInstance ().Remove (this);}public void play() {isPause = false;}public void Pause() {isPause = true;}//设置回调函数,可以设置多个回调函数public void setOnComplete(OnComplete OnC) {onComplete += OnC;}public void runOnComplete() {if (onComplete != null) {onComplete ();}if (autoKill) {Kill ();}}//设置是否杀死自动杀死协程的方法public void setAutoKill(bool b) {autoKill = b;}}下面是具体的扩展动作类的实现,这里我们先扩展一个方法DoRotate。因为老师网站上已经为我们写好了大致框架,我们只需要完成一些具体的功能即可。public static class extension_method{//在给定的时间内旋转一定角度public static IEnumerator DoRotate(this MonoBehaviour mono, dotween dot) {//计算出要旋转的角度Vector3 angle = (dot.target - dot.trans.position) / dot.time;for (float f = 0.0f; f <= dot.time; f += Time.deltaTime) {dot.trans.Rotate (angle*Time.deltaTime);//Debug.Log ("rotate:");yield return null;//如果isPause变量值为true,表示动作暂停,则接下来动作不会执行while (dot.isPause == true) {yield return null;}}//执行完后,进行广播dot.runOnComplete ();}public static dotween DoRotate(this Transform transform, Vector3 target, float time) {MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];//新建一个动作dotweendotween dot = new dotween ("DoRotate", transform, target, time, null);//为该方法新建协程Coroutine coroutine = mono.StartCoroutine (mono.DoRotate (dot));//设置协程dot.setCoroutine (coroutine);return dot;}}然后一个具体的扩展方法就完成了。我们来看一下具体的运动效果初始的位置和旋转角度旋转后的角度,可以看出物体的角度发生了旋转,我们的扩展方法实现了。我们当前只是实现了一个简单的动作,为了更好的管理更多动作,我们还要设置一个工厂,管理具体的动作的产生和税收,下面是工厂类DotweenFactory的实现public class DotweenFactory {private static List<dotween> dotList = new List<dotween> ();private static DotweenFactory dot = null;//单实例模式public static DotweenFactory getInstance() {if (dot == null) {dot = new DotweenFactory ();}return dot;}//添加一个dotween对象public void Add(dotween d) {dotList.Add (d);}//移除一个dotween对象public void Remove(dotween d) {dotList.Remove (d);}//暂停所有动作public static void PauseAll() {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {dotList [i].Pause ();}}//暂停特定变量名的动作public static void Pause(string s) {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {if (dotList [i].name == s) {dotList [i].Pause ();Debug.Log (s, "has been paused");}}}//演示所有动作public static void playAll() {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {dotList [i].play ();}}//演示特定方法名的动作public static void play(string s) {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {if (dotList [i].name == s) {dotList [i].play ();Debug.Log (s, "has been played");}}}//杀死所有动作public static void KillAll() {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {dotList [i].Kill ();}}//杀死特定方法名的动作public static void Kill(string s) {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {if (dotList [i].name == s) {dotList [i].Kill ();Debug.Log (s, "has been killed");}}}}刚才我们只扩展了一个动作,现在我们来扩展接下来两个动作,分别是平移和改变大小。代码如下。public static IEnumerator DoTranslate(this MonoBehaviour mono, dotween dot) {Vector3 dis = (dot.target - dot.trans.position) / dot.time;for (float f = 0.0f; f <= dot.time; f += Time.deltaTime) {dot.trans.Translate (dis * Time.deltaTime);//Debug.Log ("transform:");yield return null;while (dot.isPause == true) {yield return null;}}dot.runOnComplete ();}public static dotween DoTranslate(this Transform transform, Vector3 target, float time) {MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];dotween dot = new dotween ("DoTranslate", transform, target, time, null);Coroutine coroutine = mono.StartCoroutine (mono.DoTranslate (dot));dot.setCoroutine (coroutine);return dot;}public static IEnumerator DoScale(this MonoBehaviour mono, dotween dot) {Vector3 scale = (dot.target - dot.trans.position) / dot.time;for (float f = 0.0f; f <= dot.time; f += Time.deltaTime) {dot.trans.localScale += scale * Time.deltaTime;//Debug.Log ("changeScale:");yield return null;while (dot.isPause == true) {yield return null;}}dot.runOnComplete ();}public static dotween DoScale(this Transform transform, Vector3 target, float time) {MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];dotween dot = new dotween ("DoScale", transform, target, time, null);Coroutine coroutine = mono.StartCoroutine (mono.DoScale (dot));dot.setCoroutine (coroutine);return dot;}}接下来是测试代码,这里将动作和工厂一起测试。初始位置结束后可以看出运动到了我们想要的位置。接下来是全部的代码using System.Collections;using System.Collections.Generic;using UnityEngine;using Dotween.MyDotween;namespace Dotween.MyDotween{public class DotweenFactory {private static List<dotween> dotList = new List<dotween> ();private static DotweenFactory dot = null;public static DotweenFactory getInstance() {if (dot == null) {dot = new DotweenFactory ();}return dot;}public void Add(dotween d) {dotList.Add (d);Debug.Log ("success add");}public void Remove(dotween d) {dotList.Remove (d);}public static void PauseAll() {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {dotList [i].Pause ();}}public static void Pause(string s) {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {if (dotList [i].name == s) {dotList [i].Pause ();Debug.Log("dot has been paused");}}}public static void playAll() {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {dotList [i].play ();}}public static void play(string s) {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {if (dotList [i].name == s) {dotList [i].play ();Debug.Log ("dot has been played");}}}public static void KillAll() {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {dotList [i].Kill ();}}public static void Kill(string s) {int count = dotList.Count - 1;for (int i = count; i >= 0; i--) {if (dotList [i].name == s) {dotList [i].Kill ();Debug.Log ( "dot has been killed");}}}}public class dotween{public string name;public Coroutine coroutine = null;public Transform trans = null;public float time;public bool isPause = false;public bool autoKill = true;public Vector3 target;public delegate void OnComplete();public OnComplete onComplete = null;public dotween(string s, Transform t, Vector3 v, float ti, Coroutine c) {name = s;trans = t;target = v;time = ti;DotweenFactory.getInstance ().Add (this);}public void setCoroutine(Coroutine c) {coroutine = c;}public void Kill() {MonoBehaviour mono = trans.GetComponent<MonoBehaviour> ();mono.StopCoroutine (coroutine);//Dotween.getInstance ().Remove (this);}public void play() {isPause = false;}public void Pause() {isPause = true;}public void setOnComplete(OnComplete OnC) {onComplete += OnC;}public void runOnComplete() {if (onComplete != null) {onComplete ();}if (autoKill) {Kill ();}}public void setAutoKill(bool b) {autoKill = b;}}public static class extension_method{public static IEnumerator DoTranslate(this MonoBehaviour mono, dotween dot) {Vector3 dis = (dot.target - dot.trans.position) / dot.time;for (float f = 0.0f; f <= dot.time; f += Time.deltaTime) {dot.trans.Translate (dis * Time.deltaTime);//Debug.Log ("transform:");yield return null;while (dot.isPause == true) {yield return null;}}dot.runOnComplete ();}public static dotween DoTranslate(this Transform transform, Vector3 target, float time) {MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];dotween dot = new dotween ("DoTranslate", transform, target, time, null);Coroutine coroutine = mono.StartCoroutine (mono.DoTranslate (dot));dot.setCoroutine (coroutine);return dot;}public static IEnumerator DoRotate(this MonoBehaviour mono, dotween dot) {Vector3 angle = (dot.target - dot.trans.position) / dot.time;for (float f = 0.0f; f <= dot.time; f += Time.deltaTime) {dot.trans.Rotate (angle*Time.deltaTime);//Debug.Log ("rotate:");yield return null;while (dot.isPause == true) {yield return null;}}dot.runOnComplete ();}public static dotween DoRotate(this Transform transform, Vector3 target, float time) {MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];dotween dot = new dotween ("DoRotate", transform, target, time, null);Coroutine coroutine = mono.StartCoroutine (mono.DoRotate (dot));dot.setCoroutine (coroutine);return dot;}public static IEnumerator DoScale(this MonoBehaviour mono, dotween dot) {Vector3 scale = (dot.target - dot.trans.position) / dot.time;for (float f = 0.0f; f <= dot.time; f += Time.deltaTime) {dot.trans.localScale += scale * Time.deltaTime;//Debug.Log ("changeScale:");yield return null;while (dot.isPause == true) {yield return null;}}dot.runOnComplete ();}public static dotween DoScale(this Transform transform, Vector3 target, float time) {MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];dotween dot = new dotween ("DoScale", transform, target, time, null);Coroutine coroutine = mono.StartCoroutine (mono.DoScale (dot));dot.setCoroutine (coroutine);return dot;}} }test.csusing System.Collections;using System.Collections.Generic;using UnityEngine;using Dotween.MyDotween;public class test : MonoBehaviour {dotween dot1,dot2,dot3;DotweenFactory dotFact;// Use this for initializationvoid Start () {//transform.Rotate (Vector3.right * Time.deltaTime);dotFact = DotweenFactory.getInstance();dot1 = transform.DoRotate (new Vector3 (50, 50, 50), 5.0f);dotFact.Add (dot1);dot2 = transform.DoTranslate (new Vector3 (3, 4, 5), 5.0f);dotFact.Add (dot2);dot3 = transform.DoScale (new Vector3 (5, 5, 5), 5.0f);dotFact.Add (dot3);}// Update is called once per framevoid Update () {//transform.Rotate (Vector3.right * Time.deltaTime);}}
0 0
- unity作业——简单dotween的制作
- Unity DoTween加iTweenPath的简单使用
- Unity 动画插件 DOTween 的简单使用
- unity Dotween插件的简单介绍及示例代码
- unity Dotween插件的简单介绍及示例代码
- 【Unity】DoTween插件的使用
- unity插件Dotween的使用方法
- Unity学习记录——手牌区域的曲面化以及DOTween实现旋转
- Unity学习笔记11——UGUI动画插件DoTween
- Unity插件学习——DOTween(一)
- Unity简单的摇杆制作
- Unity3D学习(9)——DOTween简单仿写
- Unity简单的流光效果的制作
- Unity3: DoTween插件的简单使用
- 【Unity技巧】制作一个简单的NPC
- 【Unity技巧】制作一个简单的NPC
- 【Unity技巧】制作一个简单的NPC
- unity中简单的血条制作
- 从源字符串截取子串相关函数的封装
- 基础Android之通知栏Notification
- C++ 输入ctrl+z 不能再使用cin的问题
- scrapy使用记录
- 小程序问题
- unity作业——简单dotween的制作
- jQuery 和DOM对象
- 考试篇(5.2) NSE4 题库 22. 硬件加速 ❀ 飞塔 (Fortinet) 网络安全专家
- CORS跨域,java开发配置
- bzoj1565: [NOI2009]植物大战僵尸
- c++实验五
- Head First HTML 与CSS 第二版学习笔记(一)
- git 的 rev-parse 命令用法
- Ubuntu使用git管理