使用unity3d对于一些可视化强迫者来说,是一个不错的选择,但unity3d没有cocos2d的action管理机制,比如cocos2dx的CCMoveTo,CCScale等action,所以笔者通过封装action管理来实现类似cocos2dx的actionmanager。
首先需要写一个ActionManager来创建、更新、移除所有action。编写代码实现如下:
using UnityEngine;using System.Collections;using System;public class ActionManager : MonoBehaviour { private ArrayList actionList = null; private static ActionManager instance = null;//创建一个ActionManager单例 public static ActionManager Instance { get { instance = UnityEngine.Object.FindObjectOfType(typeof(ActionManager)) as ActionManager; if (instance == null) { GameObject obj = new GameObject("ActionManager");//每个场景都有一个ActionManager的gameobject来管理所有Action instance = obj.AddComponent(typeof(ActionManager)) as ActionManager; instance.InitActionList(); } return instance; } } public void InitActionList() { actionList = new ArrayList();//初始化所有Action容器 } void Update () { for (int i = 0; i < actionList.Count;i++ ) { BasicAction action = (BasicAction)actionList[i]; action.Update(); if(action.bCompleted)//bComplete变量用于判断action是否回收 { actionList.RemoveAt(i); i--; } } } public void AddMoveByAction(GameObject obj, Vector3 moveDirection, float moveDistance,Space relative, float useTime,Action cb) { actionList.Add(new MoveBy(obj, moveDirection, moveDistance,relative, useTime, cb)); } public void AddMoveToAction(GameObject obj, Vector3 targetPos, Space relative, float useTime, Action cb) { actionList.Add(new MoveTo(obj,targetPos, relative, useTime, cb)); }
public void RemoveActionByGameObject(GameObject obj)//通过gameobject来移除action { foreach (BasicAction action in actionList) { if (action.myObj.Equals(obj)) { actionList.Remove(action); break; } } } public void RemoveAllAction()//清除所有action
{ actionList.Clear(); } void OnDestroy() { actionList.Clear(); }
在所有action中具有共同的成员变量,所以需要编写基类函数来减少共同的成员变量和函数,编写action的基类BaseAction:
using UnityEngine;using System.Collections;public class BasicAction{ public bool bCompleted = false;//用于判断action是否完成 public GameObject myObj;//action作用的gameobject public BasicAction(){} public virtual void Update(){}//update函数,需要子类重写}
写完基类,就能入手一个action了,以下是一个比较简单的moveby action:
using UnityEngine;using System.Collections;using System;public class MoveBy : BasicAction { //通过具体距离和方向移动 /* * moveDirection 移动方向 * moveDistance 移动距离 * useTime 使用的时间,单位秒 */ private Vector3 speed; private float time; //private float deltaTime = 0; private Space myRelative; private Action mcb=null; private float deltaDis = 0,speedLen,moveDistance; private Vector3 targetPos; public MoveBy(GameObject obj,Vector3 moveDirection,float moveDistance,Space relative,float useTime,Action cb) { this.myObj=obj; this.mcb = cb; this.myRelative = relative; this.moveDistance = moveDistance; this.time = useTime; moveDirection.Normalize(); if (myRelative == Space.World) this.targetPos = this.myObj.transform.position + (moveDirection * moveDistance); else this.targetPos = this.myObj.transform.localPosition + (moveDirection * moveDistance); useTime *= (1 / 0.02f); speed = (moveDirection * moveDistance) / useTime; speedLen = Vector3.Distance(speed,Vector3.zero); } public override void Update() { if(myObj==null) { bCompleted = true; return; } deltaDis += speedLen; if (deltaDis >= moveDistance) { myObj.transform.localPosition = targetPos;//确保gameobject到达目标点 if (mcb != null)//完成action后可回调callback mcb(); bCompleted = true;//如果完成当前action,把action标记可以回收 } else { if (myRelative == Space.World) myObj.transform.position = new Vector3(myObj.transform.position.x + speed.x, myObj.transform.position.y + speed.y, myObj.transform.position.z + speed.z); else myObj.transform.localPosition = new Vector3(myObj.transform.localPosition.x + speed.x, myObj.transform.localPosition.y + speed.y, myObj.transform.localPosition.z + speed.z); } }}
使用例子:
ActionManager.Instance.AddMoveByAction(GameObject obj, Vector3 moveDirection, float moveDistance,Space relative, float useTime,Action cb)
以上时一个比较简单的action封装过程,你也可以通过实现多种action封装,比如moveto,rotationto,rotationby等等。
(转载时请注明出处,from 博客园:HemJohn)