修改水
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
// Crest Water System
|
||||
// Copyright © 2024 Wave Harmonic. All rights reserved.
|
||||
|
||||
// This file is subject to the Unity Companion License:
|
||||
// https://github.com/Unity-Technologies/com.unity.cinemachine/blob/593fa283bee378322337e5d9f5a7b91331a45799/LICENSE.md
|
||||
|
||||
// Lovingly adapted from Cinemachine:
|
||||
// https://github.com/Unity-Technologies/com.unity.cinemachine/blob/593fa283bee378322337e5d9f5a7b91331a45799/Editor/Utility/EmbeddedAssetHelpers.cs
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.VersionControl;
|
||||
|
||||
namespace WaveHarmonic.Crest.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for editors that receive an argument
|
||||
/// </summary>
|
||||
interface IEmbeddableEditor
|
||||
{
|
||||
void SetTypeOfHostComponent(System.Type hostType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper for drawing embedded asset editors
|
||||
/// </summary>
|
||||
sealed class EmbeddedAssetEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Create in OnEnable()
|
||||
/// </summary>
|
||||
public EmbeddedAssetEditor()
|
||||
{
|
||||
_CreateButtonGUIContent = new("Create Asset", "Create a new shared settings asset");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after the asset editor is created, in case it needs
|
||||
/// to be customized
|
||||
/// </summary>
|
||||
public OnCreateEditorDelegate _OnCreateEditor;
|
||||
public delegate void OnCreateEditorDelegate(UnityEditor.Editor editor);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the asset being edited was changed by the user.
|
||||
/// </summary>
|
||||
public OnChangedDelegate _OnChanged;
|
||||
public delegate void OnChangedDelegate(System.Type type, Object obj);
|
||||
|
||||
/// <summary>
|
||||
/// Free the resources in OnDisable()
|
||||
/// </summary>
|
||||
public void OnDisable()
|
||||
{
|
||||
DestroyEditor();
|
||||
Helpers.Destroy(_DefaultTarget);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Customize this after creation if you want
|
||||
/// </summary>
|
||||
public GUIContent _CreateButtonGUIContent;
|
||||
|
||||
UnityEditor.Editor _Editor = null;
|
||||
|
||||
System.Type _Type;
|
||||
|
||||
Object _DefaultTarget;
|
||||
|
||||
const int k_IndentOffset = 3;
|
||||
|
||||
public void DrawEditorCombo(GUIContent label, PropertyDrawer drawer, SerializedProperty property, string extension, int bottomMargin = 0)
|
||||
{
|
||||
_Type = drawer.fieldInfo.FieldType;
|
||||
|
||||
DrawEditorCombo
|
||||
(
|
||||
label,
|
||||
$"Create {property.displayName} Asset",
|
||||
$"{property.displayName.Replace(' ', '_')}",
|
||||
extension,
|
||||
string.Empty,
|
||||
false,
|
||||
property,
|
||||
bottomMargin
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this from OnInspectorGUI. Will draw the asset reference field, and
|
||||
/// the embedded editor, or a Create Asset button, if no asset is set.
|
||||
/// </summary>
|
||||
public void DrawEditorCombo
|
||||
(
|
||||
GUIContent label,
|
||||
string title,
|
||||
string defaultName,
|
||||
string extension,
|
||||
string message,
|
||||
bool indent,
|
||||
SerializedProperty property,
|
||||
int bottomMargin
|
||||
)
|
||||
{
|
||||
UpdateEditor(property);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var rect = AssetField(label, property, title, defaultName, extension, message);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
UpdateEditor(property);
|
||||
}
|
||||
|
||||
// Display embedded editor.
|
||||
if (_Editor != null)
|
||||
{
|
||||
var foldoutRect = new Rect(rect.x - k_IndentOffset, rect.y, rect.width + k_IndentOffset, EditorGUIUtility.singleLineHeight);
|
||||
property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, GUIContent.none, true);
|
||||
|
||||
var canEditAsset = AssetDatabase.IsOpenForEdit(_Editor.target, StatusQueryOptions.UseCachedIfPossible);
|
||||
|
||||
// We take the current GUI state into account to support attribute stacking.
|
||||
var guiEnabled = GUI.enabled;
|
||||
GUI.enabled = guiEnabled && canEditAsset;
|
||||
|
||||
if (property.isExpanded)
|
||||
{
|
||||
var level = EditorGUI.indentLevel;
|
||||
EditorGUI.indentLevel = 0;
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
// NOTE: Tweaked for current usage but probably will not work everywhere.
|
||||
if (level > 0) GUILayout.Space(8 * (level + 2));
|
||||
EditorGUILayout.BeginVertical(GUI.skin.box);
|
||||
|
||||
if ((_Editor.target.hideFlags & HideFlags.NotEditable) == 0)
|
||||
{
|
||||
EditorGUILayout.HelpBox("This is a shared asset. Changes made here will apply to all users of this asset.", MessageType.Info);
|
||||
}
|
||||
EditorGUI.BeginChangeCheck();
|
||||
_Editor.OnInspectorGUI();
|
||||
if (EditorGUI.EndChangeCheck() && (_OnChanged != null))
|
||||
_OnChanged(_Type, property.objectReferenceValue);
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (bottomMargin > 0)
|
||||
{
|
||||
EditorGUILayout.Space(bottomMargin);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable GUI so the checkout button works.
|
||||
GUI.enabled = true;
|
||||
|
||||
if (_Editor.target != null)
|
||||
{
|
||||
if (!canEditAsset && GUILayout.Button("Check out"))
|
||||
{
|
||||
var task = Provider.Checkout(AssetDatabase.GetAssetPath(_Editor.target), CheckoutMode.Asset);
|
||||
task.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
// Restore stacked GUI enabled state.
|
||||
GUI.enabled = guiEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
Rect AssetField
|
||||
(
|
||||
GUIContent label,
|
||||
SerializedProperty property,
|
||||
string title,
|
||||
string defaultName,
|
||||
string extension,
|
||||
string message
|
||||
)
|
||||
{
|
||||
return EditorHelpers.AssetField
|
||||
(
|
||||
_Type,
|
||||
label,
|
||||
property,
|
||||
EditorGUILayout.GetControlRect(true),
|
||||
title,
|
||||
defaultName,
|
||||
extension,
|
||||
message,
|
||||
x => ScriptableObject.CreateInstance(_Type)
|
||||
);
|
||||
}
|
||||
|
||||
public void DestroyEditor()
|
||||
{
|
||||
if (_Editor != null)
|
||||
{
|
||||
Object.DestroyImmediate(_Editor);
|
||||
_Editor = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateEditor(SerializedProperty property)
|
||||
{
|
||||
var target = property.objectReferenceValue;
|
||||
|
||||
if (target == null && _DefaultTarget == null)
|
||||
{
|
||||
_DefaultTarget = ScriptableObject.CreateInstance(_Type);
|
||||
_DefaultTarget.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
|
||||
}
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
target = _DefaultTarget;
|
||||
}
|
||||
|
||||
// Destroy the editor if target has changed.
|
||||
if (_Editor != null && _Editor.target != target)
|
||||
{
|
||||
DestroyEditor();
|
||||
}
|
||||
|
||||
if (_Editor != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: This is triggered twice on asset switch for some reason.
|
||||
// Create editor if need one.
|
||||
if (target != null)
|
||||
{
|
||||
_Editor = UnityEditor.Editor.CreateEditor(target);
|
||||
|
||||
// Pass through argument for editors that receive it
|
||||
if (property.serializedObject.targetObject != null)
|
||||
{
|
||||
(_Editor as IEmbeddableEditor)?.SetTypeOfHostComponent(property.serializedObject.targetObject.GetType());
|
||||
}
|
||||
|
||||
_OnCreateEditor?.Invoke(_Editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user