使用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)

最新文章

  1. phpexcel导入数据提示失败
  2. notepad++与vivado关联
  3. 常用到的git,mvn,postgres,vim命令总结
  4. 容器使用的12条军规——《Effective+STL中文版》试读
  5. centos 安装依赖错误
  6. php常见问题
  7. Apache的虚拟主机配置
  8. 微软职位内部推荐-SR DEV
  9. Android渠道汇总
  10. SSRS中加入书签功能及数据集窗口
  11. java中memcached
  12. runtime的概念,message send如果寻找不到相应的对象,如何进行后续处理
  13. 字符转十六进制 String =&gt; HEX using &quot;hexdump&quot; on linux
  14. [Kafka] - Kafka Java Consumer实现(一)
  15. Linux 小知识翻译 - 「日志」(log)
  16. jQuery EasyUI 选项卡面板tabs使用实例精讲
  17. minicom 抓取log
  18. Codeforces 830C Bamboo Partition (看题解)
  19. 2018.11.05 bzoj2143: 飞飞侠(最短路)
  20. CentOS 7下安装Python3.5

热门文章

  1. appium运行遇到的坑01
  2. Prefix.pch文件的用法
  3. IOS 转场动画二和透明控制器视图
  4. JMeter(5) JMeter之BeanShell使用
  5. C# ExpandoObject用法
  6. Codeforces Round #561 (Div. 2) B. All the Vowels Please
  7. Hive进阶_Hive数据查询
  8. RESTful API设计相关
  9. ruby 数组array 排序sort 和sort!
  10. EF+mvc+mysql