91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Unity3D中使用撤回命令

發布時間:2021-05-26 10:11:41 來源:億速云 閱讀:498 作者:Leah 欄目:編程語言

如何在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++)
  {
   //利用對象池技術回收物體 這里就不寫了 因為還要把對象池的腳本添加進來
  }
 }
}

關于如何在Unity3D中使用撤回命令問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江安县| 吉林省| 余干县| 乐至县| 鄂托克旗| 龙游县| 克东县| 海门市| 南和县| 宁强县| 德昌县| 宁明县| 固安县| 凌云县| 长海县| 会泽县| 营口市| 靖西县| 班玛县| 黑龙江省| 五峰| 通化市| 石河子市| 偃师市| 江津市| 图木舒克市| 青阳县| 镇安县| 略阳县| 武胜县| 海阳市| 睢宁县| 农安县| 山阳县| 枣庄市| 南安市| 若羌县| 马山县| 大城县| 象州县| 庆阳市|