Unity Editor 編輯器擴展 八 Undo

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

發佈了31 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章