Unity3D撤回命令开发详解
本文实例为大家分享了Unity3D撤回命令功能开发,供大家参考,具体内容如下
在类似操作考核的项目中我们经常会遇到回到上一步的需求。所以我们有必要对每一个状态点的所有参与交互的物体的状态进行记录。好了,下面就是代码的实现:
首先肯定要创建命令的基类,
public class BaseCommand { //执行命令 public virtual void ExcuteCommand() { } //撤销命令 public virtual void RevocationCommand() { } }
因为我们控制物体的类似移动改变方式不同,有可能是直接移动的,有可能是用的dotween来操作移动,所以我们的执行命令函数可能对于我们没有实现的必要。下面我们要创建一个用来管理命令的脚本,供我们添加和移除命令,同时这个脚本我们给设置为单例,可供全局调用。如下:
public class CommandManager : MonoBehaviour { public static CommandManager Instance = null; //管理命令 private Stack<BaseCommand> commandStack = new Stack<BaseCommand>(); private void Awake() { Instance = this; } //增加命令 public void AddCommand(BaseCommand baseCommand) { commandStack.Push(baseCommand); } //移除命令 并且撤销一步操作 public void RemoveCommand() { if(commandStack.Count>0) { BaseCommand baseCommand = commandStack.Pop(); baseCommand.RevocationCommand(); } } }
有个命令基类,有了管理类,下面我们就要对不同命令进行专门的功能实现了。
一.移动类命令
//保存模型的位置 角度 大小信息 public class TransformCommand : BaseCommand { private Transform target; private Vector3 pos; private Vector3 rota; private Vector3 scale; private Transform parent; //我们在构造函数里直接传进来我们改变状态前的Transform信息 public TransformCommand(Transform target, Vector3 pos, Vector3 rota, Vector3 scale,Transform parent) { this.target = target; this.pos = pos; this.rota = rota; this.scale = scale; this.parent = parent; } public override void ExcuteCommand() { base.ExcuteCommand(); } public override void RevocationCommand() { target.SetParent(parent); target.transform.localPosition = pos; target.transform.localEulerAngles = rota; target.transform.localScale = scale; } }
下面是我们写的测试脚本挂在到摄像头上,
public class CameraMove : MonoBehaviour { // Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.W)) { TransformCommand cmd = new TransformCommand(transform,transform.localPosition, transform.localEulerAngles,transform.localScale,null); CommandManager.Instance.AddCommand(cmd); transform.Translate(Vector3.forward,Space.Self); } } }
还需要写一个输入的类来调用撤退命令,代码如下:
public class Test : MonoBehaviour { private void Update() { if(Input.GetKeyDown(KeyCode.Escape)) { CommandManager.Instance.RemoveCommand(); } } }
二.UI类用户控制改变状态
下面以InputField为例,介绍UI交互类的撤退命令,这个要比普通的麻烦一些。我找了官方文档好久也没发现值改变前得回掉函数,所以只能自己来实现了。首先我们要自己写一个脚本用来记录改变之前的值。挂载在场景里的InputField上。代码如下:
public class MyInputField : MonoBehaviour,IPointerClickHandler { private InputField input; private string preString;//用来记录改变前得值 private bool IsValueChange = false;//判断值是否发生改变 private bool IsClick = false;//用来判断InputField是否被选中交互 private void Awake() { input = GetComponent<InputField>(); input.onValueChanged.AddListener(delegate { IsValueChange=true; }); input.onEndEdit.AddListener(OnEndEditCallBck); } //结束编辑得回调函数 void OnEndEditCallBck(string content) { IsClick = false; //如果值没变 直接返回 没必要增加命令 if (IsValueChange == false) return; InputFieldCommand cmd = new InputFieldCommand(input,preString); CommandManager.Instance.AddCommand(cmd); } //当被点击时,我们的UI组件被交互 有被更改值得可能 所以要记录当前值 public void OnPointerClick(PointerEventData eventData) { Debug.Log("点击"); if (IsClick) return; preString = input.text; IsClick = true; } } public class InputFieldCommand : BaseCommand { private InputField targetInput; private string content; public InputFieldCommand(InputField inputField,string content) { this.targetInput = inputField; this.content = content; } public override void RevocationCommand() { base.RevocationCommand(); targetInput.text = content; } }
上面就是在用户对InputField输入内容改变时自动记录上一步得命令。对于其他得UI组件类似Toggle Slider同样适用。
三.销毁生成的物体
我们在当前一步实例化很多物体,返回上一步就需要销毁所有实例化的物体。这里我们不建议直接销毁,而是利用对象池技术进行回收,还节约性能。对象池技术博客地址:点击打开链接 代码如下:
public class DestoryCommand : BaseCommand { private List<GameObject> objects; public DestoryCommand(List<GameObject> objects) { this.objects = objects; } public override void RevocationCommand() { for(int i=0;i< objects.Count;i++) { //利用对象池技术回收物体 这里就不写了 因为还要把对象池的脚本添加进来 } } }
这个命令是在我们实例化物体后才能增加。其实就是把实例化的物体加入到List数组然后传入一个新声明的DestoryCommand构造函数中。以上效果图如下:
希望本博客对你有帮助!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
您可能感兴趣的文章
- 01-10Unity3d获取系统时间
- 01-10Unity3D获取当前键盘按键及Unity3D鼠标、键盘的基本操作
- 01-10C# 设计模式系列教程-命令模式
- 01-10C#使用WinRar命令进行压缩和解压缩操作的实现方法
- 01-10C#使用dir命令实现文件搜索功能示例
- 01-10C# 使用相同权限调用 cmd 传入命令的方法
- 01-10Unity3D实现批量下载图片功能
- 01-10Unity3d实现Flappy Bird游戏
- 01-10Unity3D实现鼠标控制旋转转盘
- 01-10Unity3D实现控制摄像机移动
阅读排行
本栏相关
- 01-10C#通过反射获取当前工程中所有窗体并
- 01-10关于ASP网页无法打开的解决方案
- 01-10WinForm限制窗体不能移到屏幕外的方法
- 01-10WinForm绘制圆角的方法
- 01-10C#实现txt定位指定行完整实例
- 01-10WinForm实现仿视频播放器左下角滚动新
- 01-10C#停止线程的方法
- 01-10C#实现清空回收站的方法
- 01-10C#通过重写Panel改变边框颜色与宽度的
- 01-10C#实现读取注册表监控当前操作系统已
随机阅读
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-11ajax实现页面的局部加载
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 04-02jquery与jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10SublimeText编译C开发环境设置
- 01-10C#中split用法实例总结
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文