Unity3D 学习笔记 —— Tween对象的实现与动作管理

这周的作业我选择做Tween的实现, 一方面觉得挺好玩的(可以拓展原有系统类的方法, 想想就激动。 相当于可以把自己写的一些方法像库一样使用)。另一方面觉得的确有用, 而不是像GUI那样全程看教程或者文档跟着做就完事了(没有贬低的意思)

1. 预备知识

a. C#的拓展方法

C#的拓展方法, 就是提供了一种让我们可以为原有类添加新方法的功能。一个声明拓展方法的Demo如下:

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 initializationvoid Start () {System.Random rand = new System.Random();print (rand.NextBool ());}// Update is called once per framevoid Update () {}
}

主要注意以下几点:
1. 拓展方法要放在一个public static class里面
2. 拓展方法本身应该是静态的, 即包含 static修饰。
3. 拓展方法参数第一位代表要拓展的对象, 记得一定要用this修饰之。
4. 拓展方法后面的参数, 代表使用时需要传递的参数。

b. C#协程的使用

教程在这里: http://www.cnblogs.com/vivid-stanley/p/5272736.html
使用协程可以让程序实现类似多线程的效果。

c. 对Tween的了解。

这里当然要上DOTween 的官网:http://dotween.demigiant.com/documentation.php

还有很多,不可能一一实现,挑其中几个就好了。

2. 实现过程

a. 拓展方法的添加。

既然是说拓展方法, 那么先来两个简单的例子:

        public static Vector3 GetRGB(this Color color) {return new Vector3 (color.r, color.g, color.b);}public static Color ToColor(this Vector3 vec3) {return new Color (vec3.x, vec3.y, vec3.z);}

这两个方法分别拓展了 Color 和 Vector3 类, 相当于实现了从Vector3和Color的相互转化(取RGB值),这里在
实现 DoColor()方法时会用到。
然后是实现动作的拓展方法, 以DoMove()方法的代码为例子(其他的差不多)

        public static tween DoMove(this Transform transform, Vector3 target, float time)  {  MonoBehaviour mono = transform.GetComponents<MonoBehaviour> () [0];  tween myTween = new tween ("DoMove", transform, target, time);  Coroutine coroutine =  mono.StartCoroutine (mono.UniversalVector3Iter(myTween));  myTween.SetCoroutine (coroutine);  return myTween;  }  

这里拓展方法的参数有两个, 第一个是需要移动到的位置target, 第二个是移动时的总时间。
mono在这里乱入的原因是只有mono类才能启动协程, 所以必须得到一个mono对象。

b. 协程函数的实现

协程函数就是实现运动的部分, 为了避免重复, 我写了一个通用的协程函数(对于Vector3 类型通用)

        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) {  changeEveryFrame (myTween, distance * Time.deltaTime);yield return null;  while (myTween.isPause == true) {   yield return null;  }  }  }  myTween.OnComplete ();  }  

然后在changeEveryFrame ()方法里面确定到底调用哪种方法, 如下:

        public static void changeEveryFrame(tween myTween, Vector3 changedValue) {if (myTween.tweenType == "DoMove") {myTween.transform.Translate(changedValue);}if (myTween.tweenType == "DoRotate") {myTween.transform.Rotate (changedValue);  }if (myTween.tweenType == "DoScale") {myTween.transform.localScale += changedValue; }if (myTween.tweenType == "DoColor") {myTween.material.color = (myTween.material.color.GetRGB () + changedValue).ToColor ();}if (myTween.tweenType == "DoFade") {Color c = new Color (myTween.material.color.r, myTween.material.color.g, myTween.material.color.b, myTween.material.color.a + changedValue.x);myTween.material.color = c;}}

c. Tween 的实现

Tween我认为就是对这个动作协程管理的工具。代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ExtendMethods;
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 tween(string type, Transform trans, Vector3 tar, float ti) {  tweenType = type;  transform = trans;  material = trans.GetComponent<MeshRenderer> ().material;target = tar;  time = ti;  setOrigin (trans);loops = 1;  currentLoop = 0;  isPause = false;  autoKill = true;  coroutine = null;  onComplete = null;  }  public void Reset() {if (tweenType == "DoMove") {transform.position = origin;}if (tweenType == "DoRotate") {transform.position = origin;}if (tweenType == "DoScale") {transform.position = origin;}if (tweenType == "DoColor") {material.color = origin.ToColor();}if (tweenType == "DoFade") {Color c = new Color (material.color.r, material.color.g, material.color.b, origin.x);material.color = c;}}public void setOrigin(Transform transform) {if (tweenType == "DoMove") {origin = transform.position;}if (tweenType == "DoRotate") {origin = transform.rotation.eulerAngles;}if (tweenType == "DoScale") {origin = transform.localScale;}if (tweenType == "DoColor") {origin = material.color.GetRGB();}if (tweenType == "DoFade") {origin = new Vector3 (material.color.a, 0, 0);}}public tween SetLoops(int l) {  loops = l;  return this;  }  public tween SetCoroutine(Coroutine c) {  coroutine = c;  return this;  }  public tween SetAutoKill(bool auto) {  autoKill = auto;  return this;  }  public tween SetOnComplete(Callback c) {  onComplete += c;  return this;  }  public tween SetOnKill(Callback c) {  onKill += c;  return this;  }  public tween SetOnPause(Callback c) {  onPause += c;  return this;  }  public void Pause() {  isPause = true;  }  public void Play() {  isPause = false;  }  public void Restart() {  Reset ();Play ();  }  public void Complete() {  OnComplete ();  }  public void Kill() {  MonoBehaviour mono = transform.GetComponent<MonoBehaviour> ();  mono.StopCoroutine (coroutine);    }  public void OnComplete() {if (onComplete != null) {  onComplete ();  }  if (autoKill) {  Kill ();  }  }  public void OnKill() {  if (onKill != null) {  onKill ();  }  }  public void OnPause() {  if (onPause != null) {  onPause ();  }}
}

根据代码可以看到, 我一共实现了5个动作,DoMove(), DoRotate(), DoScale(), DoFade(), DoColor()

d. 效果测试

测试代码如下:

        myTween = transform.DoFade (new Vector3 (0.0f, 0f, 0f), 3.0f).SetLoops(3);  myTween = transform.DoRotate (new Vector3(150f, 0f, 0f), 3.0f).SetLoops(3);




可以看到两者同时进行, 互不干扰。
其他的测试与此类似。

3. 实验思考

不足之处:

1. if…else 用得比较多, 面向对象思想不够
2. 有些代码用Lambda函数可能更好,更简洁。
3.只实现了动作的并行, 没有实现串行(就是一个接一个的Sequence)

Unity3D 学习笔记 —— Tween对象的实现与动作管理相关推荐

  1. Unity3D学习笔记之二资源导入以及工程管理

    本次教程,我们来建立自己的一个工程并导入模型,对模型进行处理.       特别说明:这系列教程参考自人人素材翻译组出品的翻译教程<Unity游戏引擎的基础入门视频教程>,本博客中采用的模 ...

  2. Unity3D 学习笔记4 —— UGUI+uLua游戏框架

    Unity3D 学习笔记4 -- UGUI+uLua游戏框架 使用到的资料下载地址以及基础知识 框架讲解 拓展热更过程 在这里我们使用的是uLua/cstolua技术空间所以提供的UGUI+uLua的 ...

  3. Unity3D学习笔记6——GPU实例化(1)

    文章目录 1. 概述 2. 详论 3. 参考 1. 概述 在之前的文章中说到,一种材质对应一次绘制调用的指令.即使是这种情况,两个三维物体使用同一种材质,但它们使用的材质参数不一样,那么最终仍然会造成 ...

  4. Unity3D学习笔记8——GPU实例化(3)

    文章目录 1. 概述 2. 详论 2.1. 自动实例化 2.2. MaterialPropertyBlock 3. 参考 1. 概述 在前两篇文章<Unity3D学习笔记6--GPU实例化(1) ...

  5. unity3d 学习笔记四 skybox(天空盒) light(光源) halo(光晕)

    Unity3D学习笔记(四)天空.光晕和迷雾 六年前第一次接触<魔兽世界>的时候,被其绚丽的画面所折服,一个叫做贫瘠之地的地方,深深印在我的脑海里.当时在艾泽拉斯大陆还不能使用飞行坐骑,试 ...

  6. Unity3D学习笔记:粒子特效参数

    Unity3D学习笔记:粒子特效参数含义 转载 https://blog.csdn.net/asd237241291/article/details/8433534 粒子特效 粒子系统检视面板 初始化 ...

  7. Unity3D学习笔记12——渲染纹理

    文章目录 1. 概述 2. 详论 3. 问题 1. 概述 在文章<Unity3D学习笔记11--后处理>中论述了后处理是帧缓存(Framebuffer)技术实现之一:而另外一个帧缓存技术实 ...

  8. Unity3D学习笔记(二、小球滚动吃金币)

    源码:键盘方向键操作小球滚动吃金币Unity3D源码 下篇:Unity3D学习笔记(三.小球跑酷) 一.颜色材质球创建  二.Plane平板创建 三.围墙 同理二,新建Cube,并调整属性,设立围墙 ...

  9. JavaScript学习笔记:对象

    JavaScript学习笔记:对象 1.声明对象 (1)字面量对象 <!DOCTYPE html> <html lang="en"> <head> ...

  10. es6学习笔记-顶层对象_v1.0_byKL

    es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是global对象. ES5之中,顶层 ...

最新文章

  1. 【数学与算法】贝塞尔曲线
  2. SAP Basis如何显示SAP中所有用户列表
  3. Spring事务管理amp;数据库隔离级别
  4. SLAM: SLAM基本流程—VSLAM扫盲之旅
  5. 类Unix系统下,vim各种模式之间的切换
  6. 第一次“2016第三届科学数据大会”新闻发布会在上海举行
  7. +++++++子域授权与编译安装(一)
  8. php raido mysql,linux – 如何停止并修复已失败且I / O挂起的RAID 5阵列?
  9. 【干货】小米用户画像实战.pdf(附下载链接)
  10. 怎样解决jsp:include标签在包括html文件时遇到的乱码问题
  11. IT项目角色标准定义
  12. Html 中判断某个class的个数
  13. 云锁惊艳亮相2016杭州云栖大会
  14. ruby入门tips
  15. 计算机odbc数据源管理位置,ODBC数据源管理器的主要功能是什么 ODBC数据源怎么配置...
  16. 在iPhone任何界面截图完整图文教程
  17. Postgresql临时表
  18. Bridge 双维度扩展
  19. 一招解决 npm i 安装 node-sass 出现错误
  20. 消防工程师 8.2 防排烟系统-防烟

热门文章

  1. 边境的悍匪—机器学习实战:第八章 降维
  2. 又一个奇葩要求,Python是如何将“中文”转“拼音”的?
  3. 禁用 SQL 游标,告诉你外面听不到的原因
  4. python九宫格拼图_利用Python实现朋友圈中的九宫格图片效果
  5. 为啥UI设计的值放到android studio中显示不准确?
  6. 服务器2008r2启动修复,Windows Server 2008 R2原生启动试用
  7. AddressBook
  8. 网上流传房地产崩盘时间表 楼市重蹈日本覆辙 - 新闻中心 - 搜狐焦点网
  9. 前方高能!公司来了一个low逼程序员
  10. 图片合成雾的方法概述