Skip to content

Instantly share code, notes, and snippets.

@MechWarrior99
Last active February 17, 2022 04:11
Show Gist options
  • Save MechWarrior99/47a361fbc04653646874bba8ce2a7868 to your computer and use it in GitHub Desktop.
Save MechWarrior99/47a361fbc04653646874bba8ce2a7868 to your computer and use it in GitHub Desktop.
A utility class for working with Unity's Undo class. Mainly contains UndoPerformed and RedoPerformed events
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using Object = UnityEngine.Object;
/// <summary>
/// Additional utilities for use with <see cref="Undo"/>.
/// </summary>
[InitializeOnLoad]
public static class UndoUtility
{
private static Action<List<string>, List<string>> _getRecords;
private static List<string> _undoRecords = new List<string>();
private static List<string> _redoRecords = new List<string>();
/// <summary>
/// Callback that is triggered after a undo was executed.
/// </summary>
public static event Action UndoPerformed;
/// <summary>
/// Callback that is triggered after a redo was executed.
/// </summary>
public static event Action RedoPerformed;
static UndoUtility()
{
Undo.undoRedoPerformed += OnUndoRedoPerformed;
}
private static void OnUndoRedoPerformed()
{
GetRecords(_undoRecords, _redoRecords);
// All "UndoRecordsCount" and "RedoRecordsCount" should be changed to be unique to your tool.
int previousUndoCount = SessionState.GetInt("UndoRecordsCount", 0);
int previousRedoCount = SessionState.GetInt("RedoRecordsCount", 0);
if (previousUndoCount < _undoRecords.Count && previousRedoCount > _redoRecords.Count)
{
RedoPerformed?.Invoke();
}
else
{
UndoPerformed?.Invoke();
}
SessionState.SetInt("UndoRecordsCount", _undoRecords.Count);
SessionState.SetInt("UndoRecordsCount", _redoRecords.Count);
}
public static void GetRecords(List<string> undoRecords, List<string> redoRecords)
{
if (_getRecords == null)
{
var paramTypes = new Type[] { typeof(List<string>), typeof(List<string>) };
var method = typeof(Undo).GetMethod("GetRecords", BindingFlags.NonPublic | BindingFlags.Static, Type.DefaultBinder, paramTypes, null);
_getRecords = (Action<List<string>, List<string>>)method.CreateDelegate(typeof(Action<List<string>, List<string>>));
}
_getRecords(undoRecords, redoRecords);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment