Search Unity

How to record Undo on Editor Window

Discussion in 'Immediate Mode GUI (IMGUI)' started by OverPoweredTeam, Dec 30, 2020.

  1. OverPoweredTeam

    OverPoweredTeam

    Joined:
    May 3, 2017
    Posts:
    12
    Hi! I'm doing a simple texturing script, but I don't know how to implement the undo/redo actions.

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System.ComponentModel;
    4.  
    5. #if UNITY_EDITOR
    6.  
    7. public class TexturePainter : EditorWindow
    8. {
    9.     #region Creation
    10.  
    11.     private static readonly string baseTexture = "Assets/02 - Textures/Base.png";
    12.    
    13.     private Texture2D currentTexture;    
    14.    
    15.     private string texturePath;
    16.  
    17.     private const int textureSize = 256;
    18.     #endregion  
    19.  
    20.     [MenuItem("Window/Texture Painter")]
    21.     public static void ShowWindow()
    22.     {
    23.         GetWindowWithRect(typeof(TexturePainter), new Rect(Screen.width/2, Screen.height/2, 420, 490));
    24.  
    25.     }
    26.  
    27.    
    28.     void OnGUI()
    29.     {
    30.          ...
    31.         if (currentTexture)
    32.         {
    33.             ...
    34.            
    35.             GUI.DrawTexture(new Rect(minX, minY, GUISize, GUISize), currentTexture);
    36.             PaintUpdate();
    37.         }    
    38.     }
    39.  
    40.     void OnInspectorUpdate() {    ...   }
    41.  
    42.     #region Creation
    43.  
    44.     private Texture2D CreateTexture(Texture2D text = null) {    ...   }
    45.  
    46.     private void SaveTextureAsPNG(Texture2D _texture, string path) {    ...   }
    47.  
    48.     private TextureImporter GetTextureImporter(string path) {    ...   }
    49.  
    50.  
    51.     private void SetSettings(string path) {    ...   }
    52.    
    53.     public static string MakeRelative(string filePath, string referencePath) {    ...   }
    54.  
    55.     #endregion
    56.  
    57.     #region Paint
    58.  
    59.     private void PaintUpdate()
    60.     {
    61.         Vector2 pos = Event.current.mousePosition;
    62.  
    63.         ...        
    64.  
    65.         if (IsInArea(pos, 15f))
    66.         {
    67.             if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
    68.                 PaintTexture(pos);          
    69.         }      
    70.     }
    71.  
    72.     private bool IsInArea(Vector2 pos, float margin) {    ...   }
    73.  
    74.     private void PaintTexture(Vector2 pos)
    75.     {
    76.         Color c = currentColor;
    77.  
    78.         for (i)
    79.         {
    80.             for (j)
    81.             {
    82.                 currentTexture.SetPixel(i, j, c);
    83.             }
    84.         }
    85.  
    86.         Undo.RecordObject(currentTexture, "Texture Paint");
    87.  
    88.         SaveTextureAsPNG(currentTexture, texturePath);
    89.         AssetDatabase.Refresh();      
    90.     }
    91.  
    92.     private Vector2Int GetLocalPosition(Vector2 pos)  {    ...   }
    93.  
    94.     #endregion
    95.  
    96.  
    97. }
    98.  
    99. #endif

    This is the only script I use (I've just left the important lines), the main thing is done in OnGUI() > PaintUpdate() > PaintTexture() . As you can see I use "Undo.RecordObject", and the Undo seems to be recorded (I can see "Undo - Texture Paint" in Edit menu), when doing Ctrl + Z, nothing changes.

    I need to record the undo on the texture, so when I undoing it, the texture returns to the previous state.

    Thanks for helping! :D
     
  2. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    Unity's undo serialization is going to capture SerializedProperty states, not your entire array of pixels. You're probably going to need to keep an array of "undos" around that are copies of your texture back as many steps as you want to go.