Поддержка предустановок для пользовательских типов
Используйте ObjectFactory класс в скриптах редактора, чтобы создавать новые GameObject, компоненты и ассеты, которые по умолчанию поддерживают и наследуют пресеты. ObjectFactory класс автоматически применяет к этим элементам пресеты по умолчанию.
Чтобы поддерживать и включать предварительные настройки по умолчанию для пользовательских классов, они должны наследовать от одного из следующих классов:
Окно инспектора пресета создаёт временный экземпляр вашего класса, чтобы пользователь мог менять его значения. Поэтому позаботьтесь о том, чтобы класс не влиял на другие объекты — статические значения, ассеты проекта или экземпляры в сцене — и не зависел от них.
Пример: Предварительные настройки в окне пользовательского редактора
Следующая серия примеров демонстрирует, как добавить предварительные настройки в простой EditorWindow. При создании пользовательского EditorWindow класс с настройками, которые можно сохранять в пресеты:
Используйте
ScriptableObjectдля хранения копии ваших настроек. Дополнительно добавьте атрибутCustomEditor. Система предустановок обрабатывает этот объект.Всегда используйте этот временный
ScriptableObjectInspector для отображения предустановленных параметров в вашем 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);
}
}
}