支持自定义菜单项和编辑器功能

在编辑器脚本中,使用ObjectFactory类创建新的GameObject,组件和资产。创建这些项目时,ObjectFactory该类会自动使用默认预设。您的脚本不必搜索并应用默认的Presets,因为ObjectFactory它可以为您处理。

支持新类型

要默认支持和启用预设,您的类必须继承以下内容之一:

预设检查器会创建您的类的临时实例,以便用户可以修改其值,因此请确保您的类不影响或依赖于其他对象,例如静态值,Project Assets或Scene实例。

提示:使用CustomEditor属性是可选的。

用例示例:自定义“编辑器”窗口中的预设设置

使用可以使用“预设”的设置设置自定义EditorWindow类时:

  • 使用ScriptableObject存储设置的副本。它也可以具有CustomEditor属性。预设系统处理此对象。
  • 始终使用此临时ScriptableObject检查器在UI中显示“预设”设置。这样,您的用户EditorWindow和您在编辑已保存的预设时可以拥有相同的UI 。
  • 当在“ **选择预设”窗口中选择“预设”**时,公开一个“预设”按钮,并使用自己的PresetSelectorReceiver实现使EditorWindow设置保持最新。

以下脚本示例演示了如何将Preset设置添加到简单的EditorWindow

此脚本示例演示了一个ScriptableObject,该脚本可保留并显示自定义窗口中的设置(保存到名为Editor / MyWindowSettings.cs的文件中):

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自定义窗口中使用的脚本(保存到名为Editor / MySettingsReceiver.cs的文件中*)*:

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及其“预设”按钮(保存到名为Editor / MyEditorWindow.cs的文件*)*显示自定义设置:

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_SettingsEditor = Editor.CreateEditor(m_SerializedSettings);
  }

  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);
      }
  }
}
隐藏边栏