Unity 6.3
0 онлайн 106 гостей 3 в системе
Вход
Ассеты и медиа Шаг 77 из 148

Поддержка предустановок для пользовательских типов

Используйте ObjectFactory класс в скриптах редактора, чтобы создавать новые GameObject, компоненты и ассеты, которые по умолчанию поддерживают и наследуют пресеты. ObjectFactory класс автоматически применяет к этим элементам пресеты по умолчанию.

Чтобы поддерживать и включать предварительные настройки по умолчанию для пользовательских классов, они должны наследовать от одного из следующих классов:

Окно инспектора пресета создаёт временный экземпляр вашего класса, чтобы пользователь мог менять его значения. Поэтому позаботьтесь о том, чтобы класс не влиял на другие объекты — статические значения, ассеты проекта или экземпляры в сцене — и не зависел от них.

Пример: Предварительные настройки в окне пользовательского редактора

Следующая серия примеров демонстрирует, как добавить предварительные настройки в простой EditorWindow. При создании пользовательского EditorWindow класс с настройками, которые можно сохранять в пресеты:

  • Используйте ScriptableObject для хранения копии ваших настроек. Дополнительно добавьте атрибут CustomEditor. Система предустановок обрабатывает этот объект.

  • Всегда используйте этот временный ScriptableObject Inspector для отображения предустановленных параметров в вашем UI. Это позволяет вашим пользователям иметь тот же UI в вашем EditorWindow, как при редактировании сохраненных предустановок.

  • Откройте кнопку Preset и используйте свою собственную реализацию PresetSelectorReceiver для обновления настроек EditorWindow при выборе Preset в окне Select Preset.

Следующий пример демонстрирует ScriptableObject, который хранит и показывает настройки в пользовательском окне:

using UnityEngine;

// Temporary ScriptableObject used by the Preset system

public class MyWindowSettings : ScriptableObject
{
    [SerializeField]
    string m_SomeSettings;
    
    public void Init(MyEditorWindow window)
    {
        m_SomeSettings = window.someSettings;
    }
    
    public void ApplySettings(MyEditorWindow window)
    {
        window.someSettings = m_SomeSettings;
        window.Repaint();
    }
}

В следующем примере используется PresetSelectorReceiver для обновления ScriptableObject, используемого в настраиваемом окне:

using UnityEditor.Presets;

// PresetSelector receiver to update the EditorWindow with the selected values.

public class MySettingsReceiver : PresetSelectorReceiver
{
    Preset initialValues;
    MyWindowSettings currentSettings;
    MyEditorWindow currentWindow;
    
    public void Init(MyWindowSettings settings, MyEditorWindow window)
    {
        currentWindow = window;
        currentSettings = settings;
        initialValues = new Preset(currentSettings);
    }
    
    public override void OnSelectionChanged(Preset selection)
    {
        if (selection != null)
        {
            // Apply the selection to the temporary settings
            selection.ApplyTo(currentSettings);
        }
        else
        {
            // None have been selected. Apply the Initial values back to the temporary selection.
            initialValues.ApplyTo(currentSettings);
        }
        
        // Apply the new temporary settings to our manager instance
        currentSettings.ApplySettings(currentWindow);
    }
    
    public override void OnSelectionClosed(Preset selection)
    {
        // Call selection change one last time to make sure you have the last selection values.
        OnSelectionChanged(selection);
        // Destroy the receiver here, so you don't need to keep a reference to it.
        DestroyImmediate(this);
    }
}

В следующем примере создается EditorWindow, который показывает пользовательские настройки с помощью временного ScriptableObject Inspector и его кнопки Preset:

using UnityEngine;
using UnityEditor;
using UnityEditor.Presets;

public class MyEditorWindow : EditorWindow

{
    // get the Preset icon and a style to display it
    private static class Styles
    {
        public static GUIContent presetIcon = EditorGUIUtility.IconContent("Preset.Context");
        public static GUIStyle iconButton = new GUIStyle("IconButton");

    }

    Editor m_SettingsEditor;
    MyWindowSettings m_SerializedSettings;
    
    public string someSettings
    {
        get { return EditorPrefs.GetString("MyEditorWindow_SomeSettings"); }
        set { EditorPrefs.SetString("MyEditorWindow_SomeSettings", value); }
    }
   
    // Method to open the window
    [MenuItem("Window/MyEditorWindow")]
    static void OpenWindow()
    {
        GetWindow<MyEditorWindow>();
    }

    void OnEnable()
    {
        // Create your settings now and its associated Inspector
        // that allows to create only one custom Inspector for the settings in the window and the Preset.
        m_SerializedSettings = ScriptableObject.CreateInstance<MyWindowSettings>();
        m_SerializedSettings.Init(this);
        m_SerializedSettings.hideFlags = HideFlags.DontSave;
        m_SettingsEditor = Editor.CreateEditor(m_SerializedSettings);
        m_SettingsEditor.hideFlags = HideFlags.DontSave;
    }

    void OnDisable()
    {
        Object.DestroyImmediate(m_SerializedSettings);
        Object.DestroyImmediate(m_SettingsEditor);
    }

    void OnGUI()
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("My custom settings", EditorStyles.boldLabel);
        GUILayout.FlexibleSpace();
        // create the Preset button at the end of the "MyManager Settings" line.
        var buttonPosition = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight, Styles.iconButton);

        if (EditorGUI.DropdownButton(buttonPosition, Styles.presetIcon, FocusType.Passive, Styles.iconButton))
        {
            // Create a receiver instance. This destroys itself when the window appears, so you don't need to keep a reference to it.
            var presetReceiver = ScriptableObject.CreateInstance<MySettingsReceiver>();
            presetReceiver.Init(m_SerializedSettings, this);
            // Show the PresetSelector modal window. The presetReceiver updates your data.
            PresetSelector.ShowSelector(m_SerializedSettings, null, true, presetReceiver);
        }
        EditorGUILayout.EndHorizontal();
        
        // Draw the settings default Inspector and catch any change made to it.
        EditorGUI.BeginChangeCheck();
        m_SettingsEditor.OnInspectorGUI();

        if (EditorGUI.EndChangeCheck())
        {
            // Apply changes made in the settings editor to our instance.
            m_SerializedSettings.ApplySettings(this);
        }
    }
}

Дополнительные ресурсы