Unity3D撤回命令開發(fā)詳解
本文實(shí)例為大家分享了Unity3D撤回命令功能開發(fā),供大家參考,具體內(nèi)容如下
在類似操作考核的項(xiàng)目中我們經(jīng)常會(huì)遇到回到上一步的需求。所以我們有必要對每一個(gè)狀態(tài)點(diǎn)的所有參與交互的物體的狀態(tài)進(jìn)行記錄。好了,下面就是代碼的實(shí)現(xiàn):
首先肯定要?jiǎng)?chuàng)建命令的基類,
public class BaseCommand { //執(zhí)行命令 public virtual void ExcuteCommand() { } //撤銷命令 public virtual void RevocationCommand() { } }
因?yàn)槲覀兛刂莆矬w的類似移動(dòng)改變方式不同,有可能是直接移動(dòng)的,有可能是用的dotween來操作移動(dòng),所以我們的執(zhí)行命令函數(shù)可能對于我們沒有實(shí)現(xiàn)的必要。下面我們要?jiǎng)?chuàng)建一個(gè)用來管理命令的腳本,供我們添加和移除命令,同時(shí)這個(gè)腳本我們給設(shè)置為單例,可供全局調(diào)用。如下:
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(); } } }
有個(gè)命令基類,有了管理類,下面我們就要對不同命令進(jìn)行專門的功能實(shí)現(xiàn)了。
一.移動(dòng)類命令
//保存模型的位置 角度 大小信息 public class TransformCommand : BaseCommand { private Transform target; private Vector3 pos; private Vector3 rota; private Vector3 scale; private Transform parent; //我們在構(gòu)造函數(shù)里直接傳進(jìn)來我們改變狀態(tài)前的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); } } }
還需要寫一個(gè)輸入的類來調(diào)用撤退命令,代碼如下:
public class Test : MonoBehaviour { private void Update() { if(Input.GetKeyDown(KeyCode.Escape)) { CommandManager.Instance.RemoveCommand(); } } }
二.UI類用戶控制改變狀態(tài)
下面以InputField為例,介紹UI交互類的撤退命令,這個(gè)要比普通的麻煩一些。我找了官方文檔好久也沒發(fā)現(xiàn)值改變前得回掉函數(shù),所以只能自己來實(shí)現(xiàn)了。首先我們要自己寫一個(gè)腳本用來記錄改變之前的值。掛載在場景里的InputField上。代碼如下:
public class MyInputField : MonoBehaviour,IPointerClickHandler { private InputField input; private string preString;//用來記錄改變前得值 private bool IsValueChange = false;//判斷值是否發(fā)生改變 private bool IsClick = false;//用來判斷InputField是否被選中交互 private void Awake() { input = GetComponent<InputField>(); input.onValueChanged.AddListener(delegate { IsValueChange=true; }); input.onEndEdit.AddListener(OnEndEditCallBck); } //結(jié)束編輯得回調(diào)函數(shù) void OnEndEditCallBck(string content) { IsClick = false; //如果值沒變 直接返回 沒必要增加命令 if (IsValueChange == false) return; InputFieldCommand cmd = new InputFieldCommand(input,preString); CommandManager.Instance.AddCommand(cmd); } //當(dāng)被點(diǎn)擊時(shí),我們的UI組件被交互 有被更改值得可能 所以要記錄當(dāng)前值 public void OnPointerClick(PointerEventData eventData) { Debug.Log("點(diǎn)擊"); 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輸入內(nèi)容改變時(shí)自動(dòng)記錄上一步得命令。對于其他得UI組件類似Toggle Slider同樣適用。
三.銷毀生成的物體
我們在當(dāng)前一步實(shí)例化很多物體,返回上一步就需要銷毀所有實(shí)例化的物體。這里我們不建議直接銷毀,而是利用對象池技術(shù)進(jìn)行回收,還節(jié)約性能。對象池技術(shù)博客地址:點(diǎn)擊打開鏈接 代碼如下:
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++) { //利用對象池技術(shù)回收物體 這里就不寫了 因?yàn)檫€要把對象池的腳本添加進(jìn)來 } } }
這個(gè)命令是在我們實(shí)例化物體后才能增加。其實(shí)就是把實(shí)例化的物體加入到List數(shù)組然后傳入一個(gè)新聲明的DestoryCommand構(gòu)造函數(shù)中。以上效果圖如下:
希望本博客對你有幫助!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:C#在Winform開發(fā)中使用Grid++報(bào)表
欄 目:C#教程
下一篇:沒有了
本文標(biāo)題:Unity3D撤回命令開發(fā)詳解
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/4831.html
您可能感興趣的文章
- 01-10Unity3d獲取系統(tǒng)時(shí)間
- 01-10Unity3D獲取當(dāng)前鍵盤按鍵及Unity3D鼠標(biāo)、鍵盤的基本操作
- 01-10C# 設(shè)計(jì)模式系列教程-命令模式
- 01-10C#使用WinRar命令進(jìn)行壓縮和解壓縮操作的實(shí)現(xiàn)方法
- 01-10C#使用dir命令實(shí)現(xiàn)文件搜索功能示例
- 01-10C# 使用相同權(quán)限調(diào)用 cmd 傳入命令的方法
- 01-10Unity3D實(shí)現(xiàn)批量下載圖片功能
- 01-10Unity3d實(shí)現(xiàn)Flappy Bird游戲
- 01-10Unity3D實(shí)現(xiàn)鼠標(biāo)控制旋轉(zhuǎn)轉(zhuǎn)盤
- 01-10Unity3D實(shí)現(xiàn)控制攝像機(jī)移動(dòng)


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 08-05織夢dedecms什么時(shí)候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文