• untiy3d action管理机制的编写


    使用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)(要掌握)
    简单循环流程的介绍
    基本数据类型的使用和运算符的介绍
    开辟编程语言的介绍和变量
    HTML5 元素超出部分滚动, 并隐藏滚动条
    数据库多行数据合并一行(sqlserver、Oracle、Mysql)
    Js apply方法与call方法详解 附ES6新写法
    Java实现牛顿迭代法求解平方根、立方根
    为什么在JavaScript中0.1+0.2不等于0.3?
    html5手机web页面底部菜单
  • 原文地址:https://www.cnblogs.com/HemJohn/p/4839679.html
Copyright © 2020-2023  润新知