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

untiy3d action管理机制的编写的更多相关文章

  1. 【Cocos2d-x 3.x】内存管理机制与源码分析

    侯捷先生说过这么一句话 :  源码之前,了无秘密. 要了解Cocos2d-x的内存管理机制,就得阅读源码. 接触Cocos2d-x时, Cocos2d-x的最新版本已经到了3.2的时代,在学习Coco ...

  2. IOS- 内存管理机制

    iOS平台内存常见问题 作为iOS平台的开发者,是否曾经为内存问题而苦恼过?内存莫名的持续增长,程序莫名的crash,难以发现 的内存泄漏,这些都是iOS平台内存相关的常见问题:本文将会详细介绍iOS ...

  3. Android内存进程管理机制

    参考文章: http://www.apkbus.com/android-104940-1-1.htmlhttp://blog.sina.com.cn/s/blog_3e3fcadd0100yjo2.h ...

  4. 正确认识Android的内存管理机制,合理关闭进程 (一)

    随着大家收货后会有很多乐粉晒内存,为啦方便大家,在网上搜集了一些相关Andriod管理的相关机制合理管理内存,整理下发个贴. 首先要知道Android系统是基于Linux 2.6内核开发的开源操作系统 ...

  5. IOS中内存管理机制浅解

    我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是 由系统自己管理的,放在栈上).如果一个对象创建并使用后没有得 ...

  6. JVM介绍&自动内存管理机制

    1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...

  7. Spark内存管理机制

    Spark内存管理机制 Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行 ...

  8. Android包管理机制(一) PackageInstaller的初始化

    前言 包管理机制是Android中的重要机制,是应用开发和系统开发需要掌握的知识点之一. 包指的是Apk.jar和so文件等等,它们被加载到Android内存中,由一个包转变成可执行的代码,这就需要一 ...

  9. Linux中断管理 (1)Linux中断管理机制

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

随机推荐

  1. uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵加速)

    传送门 uoj上的数据太毒了--也可能是我人傻常数大的缘故-- 三种血量的奴隶主加起来不超过\(8\)个,可以枚举每种血量的奴隶主个数,那么总的状态数只有\(165\)种,设\(dp_{t,i,j,k ...

  2. Java使用FFmpeg处理视频文件的方法教程

    这篇文章主要给大家介绍了关于Java使用FFmpeg处理视频文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 前言 本文主要 ...

  3. vuex初使用(写的当然是最简单的应用啦)

    关于vuex的简图 vuex文档:https://vuex.vuejs.org/zh-cn/installation.html 一:npm安装 npm install vuex --save 在mai ...

  4. 6.计算字段 ---SQL

    提示:客户端与服务器的格式在SQL语句内可完成的许多转换和格式化工作都可以直接在客户端应用程序内完成.但一般来说,在数据库服务器上完成这些操作比在客户端中完成要快得多. 一.拼接字段 拼接(conca ...

  5. SQL 主键

    主键: 1.任意两行都不具有的相同的主键值 2.没一列都必须有一个主键值(主键列不允许NULL值) 3.主键列中的值不允许修改或更新 4.主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行 ...

  6. Linux操作学习笔记1

    Linux只有一个根目录/,所有的文件和设备都当成是文件进行管理: pwd 打印当前工作目录 (print working directory) whoami ls  列出当前目录面的文件 ls -l ...

  7. [LOJ 2039] 「SHOI2015」激光发生器

    [LOJ 2039] 「SHOI2015」激光发生器 链接 链接 题解 分为两个部分 第一个是求直线之间的交点找到第一个触碰到的镜面 第二个是求直线经过镜面反射之后的出射光线 第一个很好做,第二个就是 ...

  8. LOJ 2288「THUWC 2017」大葱的神力

    LOJ 2288「THUWC 2017」大葱的神力 Link Solution 比较水的提交答案题了吧 第一个点爆搜 第二个点爆搜+剪枝,我的剪枝就是先算出 \(mx[i]\) 表示选取第 \(i \ ...

  9. GYM 101933D(最短路、二分、dp)

    要点 非要先来后到暗示多源最短路,求最小的最大值暗示二分 二分内部的check是关键,dp处理一下,\(dp[i]\)表示第\(i\)笔订单最早何时送达,如果在ddl之前到不了则\(return\ 0 ...

  10. T-SQL多个小计+合计,分类汇总

    select then '合计' else cast(姓名 as varchar) end 姓名, then '姓名小计' else cast(学期 as varchar) end 学期, case ...