Unity的Undo撤銷操作也是可以自定義的,當我們將自己的操作組冊到Undo事件中,那麼,我們就可以按照自己的方式撤銷操作了。
目錄
Undo操作的簡單測試
下面是一些撤銷測試,非常簡單,直接看代碼
using UnityEngine;
using UnityEditor;
public class UndoTest
{
//把選中物體位置歸零
[MenuItem("Undo/RecordObject")]
static void RecordObject ()
{
Transform transform = Selection.activeTransform;
Undo.RecordObject (transform, "Pos");
transform.position = new Vector3 (0, 0, 0);
}
//選中物體添加剛體組件
[MenuItem("Undo/AddComponent")]
static void AddComponent ()
{
GameObject go = Selection.activeGameObject;
// 添加組件,執行撤銷後將被刪除
Rigidbody rigidbody = Undo.AddComponent<Rigidbody> (go);
}
// 刪除物體
[MenuItem("Undo/DestroyObjectImmediate")]
static void DestroyObjectImmediate ()
{
GameObject go = Selection.activeGameObject;
// 註冊撤銷刪除對象
Undo.DestroyObjectImmediate (go);
}
[MenuItem("Undo/SetTransformParent")]
static void SetTransformParent ()
{
Transform root = Camera.main.transform;
Transform transform = Selection.activeTransform;
// 撤銷父子關係
Undo.SetTransformParent (transform, root, "Main Cameta");
}
// 創建一個物體,如果物體的ID含有0數字則取消創建
[MenuItem("Undo/RevertAllInCurrentGroup")]
static void RevertAllInCurrentGroup ()
{
GameObject ticket = new GameObject ("Ticket");
Undo.RegisterCreatedObjectUndo (ticket, "UndoCreate");
int number = ticket.GetInstanceID ();
int winningNumber = 0;
Debug.Log (ticket.GetInstanceID());
if (ticket.GetInstanceID ().ToString().Contains(winningNumber.ToString())) {
Undo.RevertAllInCurrentGroup ();
}
}
}
Undo操作的分組摺疊
撤銷操作可以將一系列操作分爲一組,這樣一次撤銷就可以撤銷這一組的操作了
using UnityEngine;
using UnityEditor;
public class UndoWindow : EditorWindow
{
int groupID = 0;
[MenuItem ("Window/UndoWindow")]
static void Open ()
{
GetWindow<UndoWindow> ();
}
void OnEnable ()
{
groupID = Undo.GetCurrentGroup ();
}
void OnDisable ()
{
// 摺疊撤銷操作
Undo.CollapseUndoOperations (groupID);
}
void OnGUI ()
{
if (GUILayout.Button ("Cube 生成")) {
var cube = GameObject.CreatePrimitive (PrimitiveType.Cube);
Undo.RegisterCreatedObjectUndo (cube, "Create Cube");
}
if (GUILayout.Button ("Plane 生成")) {
var plane = GameObject.CreatePrimitive (PrimitiveType.Plane);
Undo.RegisterCreatedObjectUndo (plane, "Create Plane");
}
if (GUILayout.Button ("Cylinder 生成")) {
var cylinder = GameObject.CreatePrimitive (PrimitiveType.Cylinder);
Undo.RegisterCreatedObjectUndo (cylinder, "Create Cylinder");
}
if (GUILayout.Button("摺疊撤銷操作")) {
Undo.CollapseUndoOperations (groupID);
}
if (GUILayout.Button("撤銷")) {
Undo.PerformUndo ();
}
if (GUILayout.Button("取消撤銷")) {
Undo.PerformRedo ();
}
}
}
對選中物體操作,並註冊Undo練習
將自己編寫的一些操作加入到Undo中
using UnityEngine;
using UnityEditor;
public class Example
{
[MenuItem("Example/Create Cube")]
static void CreateCube ()
{
// 創建一個cube
var cube=GameObject.CreatePrimitive (PrimitiveType.Cube);
// 註冊撤銷 參數一代表撤銷操作的物體,
// 參數二代表撤銷操作的名稱,在Edit-》undo後面有顯示,目前只支持英文
Undo.RegisterCreatedObjectUndo (cube, "Create Cube");
}
[MenuItem("Example/Random Rotate")]
static void RandomRotate ()
{
// 獲取當前選中物體
var transform = Selection.activeTransform;
if (transform) {
Undo.RecordObject (transform, "Rotate " + transform.name);
transform.rotation = Random.rotation;
}
}
[MenuItem("Example/Random Rotate2")]
static void RandomRotate2 ()
{
var transform = Selection.activeTransform;
if (transform) {
Undo.willFlushUndoRecord += () => Debug.Log ("flush");
Undo.postprocessModifications += (modifications) => {
Debug.Log ("modifications");
return modifications;
};
Undo.RecordObject (transform, "Rotate 2" + transform.name);
Debug.Log ("recorded");
transform.rotation = Random.rotation;
Debug.Log("changed");
}
}
}
將Undo操作分組,撤銷到指定位置
Undo的每一步操作都有它的ID,紀錄ID就可以實現特殊的Undo操作
using UnityEngine;
using UnityEditor;
public class ExampleWindow : EditorWindow
{
[MenuItem("Window/ExampleWindow")]
static void Open ()
{
GetWindow<ExampleWindow> ();
}
GameObject go;
int group1 = 0;
int group2 = 0;
int group3 = 0;
void OnEnable ()
{
go = Camera.main.gameObject;
}
void OnGUI ()
{
if (GUILayout.Button("給攝像機添加組件")) {
group1 = Undo.GetCurrentGroup();
Undo.AddComponent<Rigidbody> (go);
Undo.IncrementCurrentGroup();
group2 = Undo.GetCurrentGroup();
Undo.AddComponent<BoxCollider> (go);
Undo.IncrementCurrentGroup();
group3 = Undo.GetCurrentGroup();
Undo.AddComponent<ConstantForce>(go);
// 打印撤銷操作編號
Debug.Log (group1+"--"+group2+"--"+group3);
}
if (GUILayout.Button("取消到group2狀態")) {
//回到group2之前的狀態
Undo.RevertAllDownToGroup(group2);
EditorGUIUtility.ExitGUI();
}
}
}
本文工程:http://download.csdn.net/detail/warrenmondeville/9708468
本文鏈接:http://blog.csdn.net/WarrenMondeville/article/details/53577379