簡體   English   中英

如何在 Unity 中執行撤消操作?

[英]How to perform undo action in Unity?

我曾嘗試執行“撤消”操作,但實際上它曾經在編輯器模式下工作過。 它也不能在設備上工作。 我想跟蹤對象的位置、旋轉和啟用/禁用gameObject 提前致謝!

PreviousState表示有關對象先前狀態的信息,並提供撤消任何更改的方法。 PreviousStateStack包含這些對象。 在用戶代碼中:

  • 每次您的程序進行任何更改時都實例化PreviousState
  • 填寫PreviousState屬性:
財產 描述
對象 改變的對象。
價值 更改前的對象值。
行動 包含恢復值指令的委托。 它通常將PreviousState.Value設置為對象並將焦點移動到更改的 GUI 組件。 默認情況下,它只是將Value設置為Obj
  • Next step push 在PreviousStateStack中創建了PreviousState
  • 在需要撤消更改時彈出它(按下 Ctrl + Z或“撤消”按鈕)並運行PreviousState.Action
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;

namespace System
{
    /// <summary>
    /// Encapsulates a method that restores the previous state of an object.
    /// </summary>
    /// <param name="obj">Managed object to restore to previous value.</param>
    /// <param name="value">The previous state of the managed object.</param>
    public delegate void RestoreAction(ref object obj, object value, params object[] parameters);

    /// <summary>
    /// Represents the implementation of <see cref="Stack{T}"/> for storage and retrieval
    /// previous state of managed objects.
    /// </summary>
    public class PreviousStateStack : Stack<IEnumerable<PreviousState>>, IEnumerable<IEnumerable<PreviousState>>
    {
        private const int DEF_CAPACITY = 256;

        /// <summary>
        /// Initializes a new instance <see cref="PreviousStateStack"/>
        /// with initial capacity <see cref="DEF_CAPACITY"/>.
        /// </summary>
        public PreviousStateStack() : base(DEF_CAPACITY)
        {
        }

        /// <summary>
        /// Initializes a new instance <see cref="PreviousStateStack"/>
        /// with initial capacity <paramref name="capacity"/>.
        /// </summary>
        /// <param name="capacity">Initial number of elements.</param>
        public PreviousStateStack(int capacity) : base(capacity)
        {
        }

        /// <summary>
        /// Initializes a new instance <see cref="PreviousStateStack"/>
        /// with the specified stack item by the <paramref name="items"/> parameter.
        /// </summary>
        /// <param name="items">Objects <see cref="PreviousState"/> to be inserted into <see cref="Stack{T}" />.</param>
        public PreviousStateStack(params PreviousState[] items) : base(DEF_CAPACITY)
        {
            push(items);
        }

        /// <summary>
        /// Restores the previous state of the managed object,
        /// represented by this instance <see cref="PreviousState"/>.
        /// </summary>
        public void Restore()
        {
            var states = Pop();
            foreach (var state in states) state.Restore();
        }

        /// <summary>
        /// Inserts the enumerated objects <see cref="PreviousState"/> as the top element of the stack <see cref="Stack{T}" />.
        /// </summary>
        /// <param name="items">
        /// Objects <see cref="PreviousState"/> to be inserted into <see cref="Stack{T}" />.
        /// </param>
        public void Push(params PreviousState[] items)
        {
            Push((IEnumerable<PreviousState>)items);
        }
    }

    /// <summary>
    /// Provides information about the previous state of managed objects.
    /// </summary>
    [SecurityCritical]
    public sealed class PreviousState
    {
        private IntPtr _objPtr;

        private static void DefaultAction(ref object obj, object value, params object[] parameters)
        {
            try
            {
                var reference = __makeref(obj);
                __refvalue(reference, object) = value;
            }
            catch
            {
                // ignored
            }
        }

        /// <summary>
        /// Defines an action that allows you to restore the previous state of the managed object.
        /// </summary>
        public RestoreAction Action { get; } = DefaultAction;

        /// <summary>
        /// Managed object for which to store the previous value.
        /// </summary>
        public object Obj
        {
            get
            {
                var handle = GCHandle.FromIntPtr(_objPtr);
                return handle.Target;
            }
            private set
            {
                var handle = GCHandle.Alloc(value);
                _objPtr = (IntPtr) handle;
            }
        }

        /// <summary>
        /// Stores the previous value of the managed object.
        /// </summary>
        public object Value { get; }

        /// <summary>
        /// Initializes a new instance <see cref="PreviousState"/>
        /// for the specified managed object and its previous state.
        /// </summary>
        /// <param name="obj">Object for which the previous state will be saved.</param>
        /// <param name="value">The previous state of the object.</param>
        public PreviousState(object obj, object value)
        {
            obj=obj?? throw new ArgumentNullException(nameof(obj));
            value = value;
        }

        /// <summary>
        /// Initializes a new instance <see cref="PreviousState"/>
        /// for the specified managed object, its previous state, and the action by which
        /// it will be restored.
        /// </summary>
        /// <param name="obj">Object for which the previous state will be saved.</param>
        /// <param name="value">The previous state of the object.</param>
        /// <param name="action">An action that allows you to restore the previous state of the object.</param>
        public PreviousState(object obj, object value, RestoreAction action) : this(obj, value)
        {
            Action = action?? throw new ArgumentNullException(nameof(action));
        }

        /// <summary>
        /// Restores the previous state of the managed object,
        /// represented by this instance <see cref="PreviousState"/>.
        /// </summary>
        public void Restore()
        {
            objectobj = obj;
            Action?.Invoke(ref obj, this.Value);
        }
    }
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM