Unity3D Basi c Отмена сценариев - PullRequest
0 голосов
/ 13 января 2020

В настоящее время я пытаюсь настроить функцию отмены c в моей игре. В моей настройке я просто пытаюсь установить игровой объект активным от false до true. Я добавил объект undo.recordobject, чтобы единство могло отслеживать изменения, но что мне нужно делать потом? Я хотел создать кнопку, которая позволила бы конечным пользователям отменить предыдущие действия. Какие шаги я сейчас пропускаю в своих кодах, чтобы заставить мое программное обеспечение выполнять опцию отмены?

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using System;
using UnityEditor;

public class LoadAssets : MonoBehaviour
{    
    public GameObject Mud;
    public GameObject DrillFormationMain;
    public GameObject DrillFormation1;
    public GameObject DrillFormation2;
    public GameObject DrillFormation3;

    int count = 0;

    public void DrillHole()
    {
        if (count == 0)
        {
            Mud.SetActive(true);
            DrillFormationMain.SetActive(false);
            DrillFormation1.SetActive(true);

            Undo.RecordObject(DrillFormationMain, "Change");
            DrillFormationMain.transform.position = Vector3.zero;
        }

        else if (count == 1)
        {
            DrillFormation1.SetActive(false);
            DrillFormation2.SetActive(true);

            Undo.RecordObject(DrillFormation1, "Change1");
            DrillFormation1.transform.position = Vector3.zero;
        }  
        count++;
    }   
}

1 Ответ

3 голосов
/ 13 января 2020

Undo является частью пространства имен UnityEditor.

Это пространство имен (то есть имя) существует только в самом редакторе Unity и полностью удаляется в сборке

=> Вы не можете использовать что-либо из этого, включая ofcourse Undo.RecordObject для фактического кода времени выполнения, но только для пользовательских сценариев редактора.


Вам придется придумайте другое решение для вашей системы отмены / возврата.

Один очень упрощенный пример может выглядеть, например,

public class UndoableAction
{
    public UndoableActionType Type;
    public UnityEngine.Object target;
    public object from;
    public object to;

    public UndoableAction(UndoableActionType type, UnityEngine.Object target, object from, object to)
    {
        Type = type;
        Target = target;
        From = from;
        To = to;
    }
}

public enum UndoableActionType
{
    Enable,
    SetActive,
    Position,

    // ... according to your needs
}

public class UndoRedoSystem : MonoBehaviour
{
    private Stack<UndoableAction> availableUndos = new Stack<UndoableAction>();
    private Stack<UndoableAction> availableRedos = new Stack<UndoableAction>();

    public void TrackChangeAction(UndoableActionType type, UnityEngine.Object target, object from, object to)
    {
        // if you change something redo is cleared
        availableRedos.Clear();

        // Add this action do undoable actions
        availableUndos.Push(new UndoableAction(type, target, from, to));
    }

    public void Redo()
    {
        if(availableRedos.Count == 0) return;

        // get latest entry added to available Redos
        var redo = availableRedos.Pop();

        switch(redo.Type)
        {
            case UndoableActionType.Enable:
                ((Component) redo.target).enabled = (bool)redo.To;
                break;

            case UndoableActionType.SetActive:
                ((GameObject) redo.target).SetActive((bool) redo.To);
                break;

            case UndoableActionType.Position:
                ((Transform) redo.target).position = (Vector3) redo.To;
                break;

            // ... According to your needs 
        }

        // finally this is now a new undoable action
        availableUndos.Push(redo);
    }

    public void Undo()
    {
        if(availableUndos.Count == 0) return;

        // get latest entry added to available Undo
        var undo = availableUndos.Pop();

        switch(undo.Type)
        {
            case UndoableActionType.Enable:
                ((Component) undo.target).enabled = (bool)undo.From;
                break;

            case UndoableActionType.SetActive:
                ((GameObject) undo.target).SetActive((bool) undo.From);
                break;

            case UndoableActionType.Position:
                ((Transform) undo.target).position = (Vector3) undo.From;
                break;

            // ... According to your needs 
        }

        // finally this is now a new  redoable action
        availableRedos.Push(undo);
    }
}

Теперь вы можете сделать что-то вроде, например,

SomeGameObject.SetActive(true);

undoSystemReference.TrackChange((UnityEngine.Object)SomeGameObject, (object)false, (object)true);

А потом где-то

undoSystemReference.Undo();

Это, конечно, довольно упрощенно и подвержено ошибкам.


Примечание Набрано на смартфоне, поэтому никаких гарантий, но я надеюсь, идея становится понятной

...