597 lines
20 KiB
C#
597 lines
20 KiB
C#
|
|
using System.Collections.Generic;
|
||
|
|
using AlicizaX.Editor;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEditor.Callbacks;
|
||
|
|
using UnityEditor.UIElements;
|
||
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.UIElements;
|
||
|
|
|
||
|
|
namespace AlicizaX
|
||
|
|
{
|
||
|
|
public sealed class PoolConfigEditorWindow : EditorWindow
|
||
|
|
{
|
||
|
|
private const float MinLeftWidth = 240f;
|
||
|
|
private const float InitialLeftWidth = 300f;
|
||
|
|
private const int ListItemHeight = 46;
|
||
|
|
private const string WindowTitle = "Pool Config Editor";
|
||
|
|
|
||
|
|
private static readonly Color LeftPanelColor = new Color(0.22f, 0.22f, 0.22f, 1f);
|
||
|
|
private static readonly Color RightPanelColor = new Color(0.16f, 0.16f, 0.16f, 1f);
|
||
|
|
|
||
|
|
private PoolConfigScriptableObject _asset;
|
||
|
|
private SerializedObject _serializedObject;
|
||
|
|
private SerializedProperty _entriesProperty;
|
||
|
|
private readonly List<int> _entryIndices = new List<int>();
|
||
|
|
|
||
|
|
private int _selectedIndex;
|
||
|
|
private bool _hasUnsavedChanges;
|
||
|
|
|
||
|
|
private ToolbarButton _saveButton;
|
||
|
|
private Label _titleLabel;
|
||
|
|
private VisualElement _leftPane;
|
||
|
|
private ListView _listView;
|
||
|
|
private ScrollView _detailScrollView;
|
||
|
|
private Label _detailTitleLabel;
|
||
|
|
private VisualElement _detailFieldsContainer;
|
||
|
|
private VisualElement _emptyContainer;
|
||
|
|
|
||
|
|
[MenuItem("AlicizaX/GameObjectPool/Open PoolConfig Editor")]
|
||
|
|
public static void OpenWindow()
|
||
|
|
{
|
||
|
|
Open(Selection.activeObject as PoolConfigScriptableObject);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void Open(PoolConfigScriptableObject asset)
|
||
|
|
{
|
||
|
|
PoolConfigEditorWindow window = GetWindow<PoolConfigEditorWindow>(false, WindowTitle, true);
|
||
|
|
window.minSize = new Vector2(920f, 560f);
|
||
|
|
window.SetAsset(asset);
|
||
|
|
window.Show();
|
||
|
|
}
|
||
|
|
|
||
|
|
[OnOpenAsset(0)]
|
||
|
|
private static bool OnOpenAsset(int instanceId, int line)
|
||
|
|
{
|
||
|
|
Object obj = EditorUtility.InstanceIDToObject(instanceId);
|
||
|
|
if (obj is not PoolConfigScriptableObject asset)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
Open(asset);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void CreateGUI()
|
||
|
|
{
|
||
|
|
titleContent = new GUIContent(WindowTitle, EditorGUIUtility.IconContent("ScriptableObject Icon").image);
|
||
|
|
BuildUi();
|
||
|
|
|
||
|
|
if (_asset == null && Selection.activeObject is PoolConfigScriptableObject selectedAsset)
|
||
|
|
{
|
||
|
|
SetAsset(selectedAsset);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
RefreshUi();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnEnable()
|
||
|
|
{
|
||
|
|
titleContent = new GUIContent(WindowTitle, EditorGUIUtility.IconContent("ScriptableObject Icon").image);
|
||
|
|
if (rootVisualElement.childCount == 0)
|
||
|
|
{
|
||
|
|
BuildUi();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (_asset == null && Selection.activeObject is PoolConfigScriptableObject selectedAsset)
|
||
|
|
{
|
||
|
|
SetAsset(selectedAsset);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
RefreshUi();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnSelectionChange()
|
||
|
|
{
|
||
|
|
if (Selection.activeObject is PoolConfigScriptableObject selectedAsset && selectedAsset != _asset)
|
||
|
|
{
|
||
|
|
SetAsset(selectedAsset);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BuildUi()
|
||
|
|
{
|
||
|
|
rootVisualElement.Clear();
|
||
|
|
rootVisualElement.style.flexDirection = FlexDirection.Column;
|
||
|
|
|
||
|
|
Toolbar toolbar = new Toolbar();
|
||
|
|
toolbar.style.flexShrink = 0f;
|
||
|
|
|
||
|
|
_saveButton = new ToolbarButton(SaveAsset)
|
||
|
|
{
|
||
|
|
tooltip = "Save PoolConfig"
|
||
|
|
};
|
||
|
|
_saveButton.Add(new Image
|
||
|
|
{
|
||
|
|
image = EditorGUIUtility.IconContent("SaveActive").image,
|
||
|
|
scaleMode = ScaleMode.ScaleToFit
|
||
|
|
});
|
||
|
|
|
||
|
|
_titleLabel = new Label();
|
||
|
|
_titleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
|
||
|
|
_titleLabel.style.flexGrow = 1f;
|
||
|
|
_titleLabel.style.marginLeft = 6f;
|
||
|
|
_titleLabel.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||
|
|
|
||
|
|
toolbar.Add(_saveButton);
|
||
|
|
toolbar.Add(_titleLabel);
|
||
|
|
rootVisualElement.Add(toolbar);
|
||
|
|
|
||
|
|
TwoPaneSplitView splitView = new TwoPaneSplitView(0, InitialLeftWidth, TwoPaneSplitViewOrientation.Horizontal);
|
||
|
|
splitView.style.flexGrow = 1f;
|
||
|
|
rootVisualElement.Add(splitView);
|
||
|
|
|
||
|
|
_leftPane = new VisualElement();
|
||
|
|
_leftPane.style.flexGrow = 1f;
|
||
|
|
_leftPane.style.minWidth = MinLeftWidth;
|
||
|
|
_leftPane.style.backgroundColor = LeftPanelColor;
|
||
|
|
_leftPane.style.paddingLeft = 4f;
|
||
|
|
_leftPane.style.paddingRight = 4f;
|
||
|
|
_leftPane.style.paddingTop = 4f;
|
||
|
|
_leftPane.style.paddingBottom = 4f;
|
||
|
|
|
||
|
|
VisualElement rightPane = new VisualElement();
|
||
|
|
rightPane.style.flexGrow = 1f;
|
||
|
|
rightPane.style.backgroundColor = RightPanelColor;
|
||
|
|
rightPane.style.paddingLeft = 10f;
|
||
|
|
rightPane.style.paddingRight = 10f;
|
||
|
|
rightPane.style.paddingTop = 8f;
|
||
|
|
rightPane.style.paddingBottom = 8f;
|
||
|
|
|
||
|
|
splitView.Add(_leftPane);
|
||
|
|
splitView.Add(rightPane);
|
||
|
|
|
||
|
|
BuildLeftPane();
|
||
|
|
BuildRightPane(rightPane);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BuildLeftPane()
|
||
|
|
{
|
||
|
|
_listView = new ListView
|
||
|
|
{
|
||
|
|
selectionType = SelectionType.Single,
|
||
|
|
virtualizationMethod = CollectionVirtualizationMethod.FixedHeight,
|
||
|
|
reorderable = false,
|
||
|
|
showBorder = false,
|
||
|
|
showAlternatingRowBackgrounds = AlternatingRowBackground.None,
|
||
|
|
style =
|
||
|
|
{
|
||
|
|
flexGrow = 1f,
|
||
|
|
marginBottom = 4f
|
||
|
|
},
|
||
|
|
fixedItemHeight = ListItemHeight
|
||
|
|
};
|
||
|
|
|
||
|
|
_listView.makeItem = MakeListItem;
|
||
|
|
_listView.bindItem = BindListItem;
|
||
|
|
_listView.selectionChanged += _ => OnListSelectionChanged();
|
||
|
|
_leftPane.Add(_listView);
|
||
|
|
|
||
|
|
VisualElement footer = new VisualElement();
|
||
|
|
footer.style.flexDirection = FlexDirection.Row;
|
||
|
|
footer.style.justifyContent = Justify.Center;
|
||
|
|
footer.style.alignItems = Align.Center;
|
||
|
|
footer.style.flexShrink = 0f;
|
||
|
|
footer.style.height = 28f;
|
||
|
|
|
||
|
|
Button addButton = new Button(AddEntry)
|
||
|
|
{
|
||
|
|
tooltip = "Add Item"
|
||
|
|
};
|
||
|
|
addButton.style.width = 24f;
|
||
|
|
addButton.style.height = 20f;
|
||
|
|
addButton.style.marginRight = 4f;
|
||
|
|
addButton.Add(new Image
|
||
|
|
{
|
||
|
|
image = EditorUtils.Styles.PlusIcon.image,
|
||
|
|
scaleMode = ScaleMode.ScaleToFit
|
||
|
|
});
|
||
|
|
|
||
|
|
Button removeButton = new Button(RemoveEntry)
|
||
|
|
{
|
||
|
|
tooltip = "Remove Item",
|
||
|
|
name = "remove-button"
|
||
|
|
};
|
||
|
|
removeButton.style.width = 24f;
|
||
|
|
removeButton.style.height = 20f;
|
||
|
|
removeButton.Add(new Image
|
||
|
|
{
|
||
|
|
image = EditorUtils.Styles.MinusIcon.image,
|
||
|
|
scaleMode = ScaleMode.ScaleToFit
|
||
|
|
});
|
||
|
|
removeButton.SetEnabled(false);
|
||
|
|
|
||
|
|
footer.Add(addButton);
|
||
|
|
footer.Add(removeButton);
|
||
|
|
_leftPane.Add(footer);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BuildRightPane(VisualElement rightPane)
|
||
|
|
{
|
||
|
|
_emptyContainer = new VisualElement
|
||
|
|
{
|
||
|
|
style =
|
||
|
|
{
|
||
|
|
flexGrow = 1f,
|
||
|
|
justifyContent = Justify.Center
|
||
|
|
}
|
||
|
|
};
|
||
|
|
_emptyContainer.Add(new HelpBox("No entry selected.", HelpBoxMessageType.Info));
|
||
|
|
|
||
|
|
_detailScrollView = new ScrollView
|
||
|
|
{
|
||
|
|
style =
|
||
|
|
{
|
||
|
|
flexGrow = 1f
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
_detailTitleLabel = new Label();
|
||
|
|
_detailTitleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
|
||
|
|
_detailTitleLabel.style.marginBottom = 6f;
|
||
|
|
_detailTitleLabel.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||
|
|
|
||
|
|
_detailFieldsContainer = new VisualElement();
|
||
|
|
_detailFieldsContainer.style.flexDirection = FlexDirection.Column;
|
||
|
|
_detailFieldsContainer.style.flexGrow = 1f;
|
||
|
|
|
||
|
|
_detailScrollView.Add(_detailTitleLabel);
|
||
|
|
_detailScrollView.Add(_detailFieldsContainer);
|
||
|
|
|
||
|
|
rightPane.Add(_emptyContainer);
|
||
|
|
rightPane.Add(_detailScrollView);
|
||
|
|
}
|
||
|
|
|
||
|
|
private VisualElement MakeListItem()
|
||
|
|
{
|
||
|
|
VisualElement root = new VisualElement();
|
||
|
|
root.style.height = ListItemHeight;
|
||
|
|
root.style.flexDirection = FlexDirection.Column;
|
||
|
|
root.style.justifyContent = Justify.Center;
|
||
|
|
root.style.paddingLeft = 8f;
|
||
|
|
root.style.paddingRight = 8f;
|
||
|
|
root.style.paddingTop = 6f;
|
||
|
|
root.style.paddingBottom = 6f;
|
||
|
|
root.style.marginBottom = 2f;
|
||
|
|
|
||
|
|
Label primary = new Label { name = "primary" };
|
||
|
|
primary.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||
|
|
|
||
|
|
Label secondary = new Label { name = "secondary" };
|
||
|
|
secondary.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||
|
|
secondary.style.fontSize = 11f;
|
||
|
|
secondary.style.color = new Color(0.72f, 0.72f, 0.72f, 1f);
|
||
|
|
|
||
|
|
root.Add(primary);
|
||
|
|
root.Add(secondary);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void BindListItem(VisualElement element, int index)
|
||
|
|
{
|
||
|
|
SerializedProperty entry = GetEntryAt(index);
|
||
|
|
element.Q<Label>("primary").text = GetPrimaryLabel(entry);
|
||
|
|
element.Q<Label>("secondary").text = GetSecondaryLabel(entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void SetAsset(PoolConfigScriptableObject asset)
|
||
|
|
{
|
||
|
|
_asset = asset;
|
||
|
|
_selectedIndex = 0;
|
||
|
|
_hasUnsavedChanges = false;
|
||
|
|
|
||
|
|
if (_asset == null)
|
||
|
|
{
|
||
|
|
_serializedObject = null;
|
||
|
|
_entriesProperty = null;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
_asset.Normalize();
|
||
|
|
_serializedObject = new SerializedObject(_asset);
|
||
|
|
_entriesProperty = _serializedObject.FindProperty("entries");
|
||
|
|
RebuildEntryIndices();
|
||
|
|
ClampSelection();
|
||
|
|
}
|
||
|
|
|
||
|
|
RefreshUi();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RefreshUi()
|
||
|
|
{
|
||
|
|
if (_titleLabel == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
RefreshTitle();
|
||
|
|
_saveButton?.SetEnabled(_asset != null);
|
||
|
|
|
||
|
|
if (_asset == null || _serializedObject == null)
|
||
|
|
{
|
||
|
|
_entryIndices.Clear();
|
||
|
|
_listView.itemsSource = _entryIndices;
|
||
|
|
_listView.Rebuild();
|
||
|
|
_emptyContainer.Clear();
|
||
|
|
_emptyContainer.Add(new HelpBox("Select or double-click a PoolConfig asset to edit it in this window.", HelpBoxMessageType.Info));
|
||
|
|
_emptyContainer.style.display = DisplayStyle.Flex;
|
||
|
|
_detailScrollView.style.display = DisplayStyle.None;
|
||
|
|
UpdateRemoveButtonState();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
RebuildEntryIndices();
|
||
|
|
ClampSelection();
|
||
|
|
|
||
|
|
_listView.itemsSource = _entryIndices;
|
||
|
|
_listView.Rebuild();
|
||
|
|
if (_entryIndices.Count > 0)
|
||
|
|
{
|
||
|
|
_listView.SetSelectionWithoutNotify(new[] { _selectedIndex });
|
||
|
|
_emptyContainer.style.display = DisplayStyle.None;
|
||
|
|
_detailScrollView.style.display = DisplayStyle.Flex;
|
||
|
|
RebuildDetailFields();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
_emptyContainer.Clear();
|
||
|
|
_emptyContainer.Add(new HelpBox("No entry selected.", HelpBoxMessageType.Info));
|
||
|
|
_emptyContainer.style.display = DisplayStyle.Flex;
|
||
|
|
_detailScrollView.style.display = DisplayStyle.None;
|
||
|
|
}
|
||
|
|
|
||
|
|
UpdateRemoveButtonState();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RebuildEntryIndices()
|
||
|
|
{
|
||
|
|
_entryIndices.Clear();
|
||
|
|
int count = _entriesProperty?.arraySize ?? 0;
|
||
|
|
for (int i = 0; i < count; i++)
|
||
|
|
{
|
||
|
|
_entryIndices.Add(i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void UpdateRemoveButtonState()
|
||
|
|
{
|
||
|
|
Button removeButton = _leftPane?.Q<Button>("remove-button");
|
||
|
|
removeButton?.SetEnabled(_entryIndices.Count > 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnListSelectionChanged()
|
||
|
|
{
|
||
|
|
if (_listView.selectedIndex < 0 || _listView.selectedIndex >= _entryIndices.Count)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_selectedIndex = _listView.selectedIndex;
|
||
|
|
UpdateRemoveButtonState();
|
||
|
|
RebuildDetailFields();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RebuildDetailFields()
|
||
|
|
{
|
||
|
|
if (_asset == null || _serializedObject == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
SerializedProperty selectedProperty = GetSelectedProperty();
|
||
|
|
if (selectedProperty == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_serializedObject.Update();
|
||
|
|
_detailTitleLabel.text = GetPrimaryLabel(selectedProperty);
|
||
|
|
|
||
|
|
_detailFieldsContainer.Unbind();
|
||
|
|
_detailFieldsContainer.Clear();
|
||
|
|
|
||
|
|
SerializedProperty iterator = selectedProperty.Copy();
|
||
|
|
SerializedProperty end = iterator.GetEndProperty();
|
||
|
|
bool enterChildren = true;
|
||
|
|
while (iterator.NextVisible(enterChildren) && !SerializedProperty.EqualContents(iterator, end))
|
||
|
|
{
|
||
|
|
PropertyField field = new PropertyField(iterator.Copy());
|
||
|
|
field.RegisterCallback<SerializedPropertyChangeEvent>(OnDetailPropertyChanged);
|
||
|
|
_detailFieldsContainer.Add(field);
|
||
|
|
enterChildren = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
_detailFieldsContainer.Bind(_serializedObject);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnDetailPropertyChanged(SerializedPropertyChangeEvent evt)
|
||
|
|
{
|
||
|
|
if (_asset == null || _serializedObject == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||
|
|
_asset.Normalize();
|
||
|
|
_hasUnsavedChanges = true;
|
||
|
|
_listView?.RefreshItems();
|
||
|
|
RefreshTitle();
|
||
|
|
_detailTitleLabel.text = GetPrimaryLabel(GetSelectedProperty());
|
||
|
|
}
|
||
|
|
|
||
|
|
private void AddEntry()
|
||
|
|
{
|
||
|
|
if (_entriesProperty == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_serializedObject.Update();
|
||
|
|
|
||
|
|
int index = _entriesProperty.arraySize;
|
||
|
|
_entriesProperty.InsertArrayElementAtIndex(index);
|
||
|
|
SerializedProperty property = _entriesProperty.GetArrayElementAtIndex(index);
|
||
|
|
InitializeNewEntry(property, index);
|
||
|
|
|
||
|
|
_serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||
|
|
_asset.Normalize();
|
||
|
|
RebuildEntryIndices();
|
||
|
|
_selectedIndex = index;
|
||
|
|
_hasUnsavedChanges = true;
|
||
|
|
RefreshUi();
|
||
|
|
_listView.SetSelectionWithoutNotify(new[] { _selectedIndex });
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RemoveEntry()
|
||
|
|
{
|
||
|
|
if (_entriesProperty == null || _entryIndices.Count == 0)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_serializedObject.Update();
|
||
|
|
_entriesProperty.DeleteArrayElementAtIndex(_selectedIndex);
|
||
|
|
_serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||
|
|
_asset.Normalize();
|
||
|
|
RebuildEntryIndices();
|
||
|
|
|
||
|
|
if (_selectedIndex >= _entryIndices.Count)
|
||
|
|
{
|
||
|
|
_selectedIndex = Mathf.Max(0, _entryIndices.Count - 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
_hasUnsavedChanges = true;
|
||
|
|
RefreshUi();
|
||
|
|
if (_entryIndices.Count > 0)
|
||
|
|
{
|
||
|
|
_listView.SetSelectionWithoutNotify(new[] { _selectedIndex });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void InitializeNewEntry(SerializedProperty property, int index)
|
||
|
|
{
|
||
|
|
property.FindPropertyRelative("entryName").stringValue = $"PoolEntry{index + 1}";
|
||
|
|
property.FindPropertyRelative("group").stringValue = PoolEntry.DefaultGroup;
|
||
|
|
property.FindPropertyRelative("assetPath").stringValue = string.Empty;
|
||
|
|
property.FindPropertyRelative("matchMode").enumValueIndex = (int)PoolMatchMode.Exact;
|
||
|
|
property.FindPropertyRelative("loaderType").enumValueIndex = (int)PoolResourceLoaderType.AssetBundle;
|
||
|
|
property.FindPropertyRelative("overflowPolicy").enumValueIndex = (int)PoolOverflowPolicy.FailFast;
|
||
|
|
property.FindPropertyRelative("trimPolicy").enumValueIndex = (int)PoolTrimPolicy.IdleOnly;
|
||
|
|
property.FindPropertyRelative("activationMode").enumValueIndex = (int)PoolActivationMode.SetActive;
|
||
|
|
property.FindPropertyRelative("resetMode").enumValueIndex = (int)PoolResetMode.PoolableCallbacks;
|
||
|
|
property.FindPropertyRelative("minRetained").intValue = 0;
|
||
|
|
property.FindPropertyRelative("softCapacity").intValue = 8;
|
||
|
|
property.FindPropertyRelative("hardCapacity").intValue = 8;
|
||
|
|
property.FindPropertyRelative("idleTrimDelay").floatValue = 30f;
|
||
|
|
property.FindPropertyRelative("prefabUnloadDelay").floatValue = 60f;
|
||
|
|
property.FindPropertyRelative("autoRecycleDelay").floatValue = 0f;
|
||
|
|
property.FindPropertyRelative("trimBatchPerTick").intValue = 2;
|
||
|
|
property.FindPropertyRelative("warmupBatchPerFrame").intValue = 2;
|
||
|
|
property.FindPropertyRelative("warmupFrameBudgetMs").floatValue = 1f;
|
||
|
|
property.FindPropertyRelative("allowRuntimeExpand").boolValue = false;
|
||
|
|
property.FindPropertyRelative("keepPrefabResident").boolValue = false;
|
||
|
|
property.FindPropertyRelative("aggressiveTrimOnLowMemory").boolValue = false;
|
||
|
|
property.FindPropertyRelative("priority").intValue = index;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void SaveAsset()
|
||
|
|
{
|
||
|
|
if (_asset == null || _serializedObject == null)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_serializedObject.ApplyModifiedProperties();
|
||
|
|
_asset.Normalize();
|
||
|
|
EditorUtility.SetDirty(_asset);
|
||
|
|
AssetDatabase.SaveAssets();
|
||
|
|
_serializedObject.Update();
|
||
|
|
_hasUnsavedChanges = false;
|
||
|
|
RefreshUi();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void RefreshTitle()
|
||
|
|
{
|
||
|
|
string assetLabel = _asset == null ? "No PoolConfig Selected" : _asset.name;
|
||
|
|
if (_hasUnsavedChanges)
|
||
|
|
{
|
||
|
|
assetLabel += " *";
|
||
|
|
}
|
||
|
|
|
||
|
|
_titleLabel.text = assetLabel;
|
||
|
|
}
|
||
|
|
|
||
|
|
private SerializedProperty GetEntryAt(int index)
|
||
|
|
{
|
||
|
|
return _entriesProperty == null || index < 0 || index >= _entriesProperty.arraySize
|
||
|
|
? null
|
||
|
|
: _entriesProperty.GetArrayElementAtIndex(index);
|
||
|
|
}
|
||
|
|
|
||
|
|
private SerializedProperty GetSelectedProperty()
|
||
|
|
{
|
||
|
|
if (_entryIndices.Count == 0)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
ClampSelection();
|
||
|
|
return GetEntryAt(_selectedIndex);
|
||
|
|
}
|
||
|
|
|
||
|
|
private string GetPrimaryLabel(SerializedProperty property)
|
||
|
|
{
|
||
|
|
if (property == null)
|
||
|
|
{
|
||
|
|
return "<Missing>";
|
||
|
|
}
|
||
|
|
|
||
|
|
string entryName = property.FindPropertyRelative("entryName").stringValue;
|
||
|
|
string assetPath = property.FindPropertyRelative("assetPath").stringValue;
|
||
|
|
if (!string.IsNullOrWhiteSpace(entryName))
|
||
|
|
{
|
||
|
|
return entryName;
|
||
|
|
}
|
||
|
|
|
||
|
|
return string.IsNullOrWhiteSpace(assetPath) ? "<Unnamed Entry>" : assetPath;
|
||
|
|
}
|
||
|
|
|
||
|
|
private string GetSecondaryLabel(SerializedProperty property)
|
||
|
|
{
|
||
|
|
if (property == null)
|
||
|
|
{
|
||
|
|
return string.Empty;
|
||
|
|
}
|
||
|
|
|
||
|
|
string group = property.FindPropertyRelative("group").stringValue;
|
||
|
|
string assetPath = property.FindPropertyRelative("assetPath").stringValue;
|
||
|
|
return string.IsNullOrWhiteSpace(assetPath) ? group : $"{group} | {assetPath}";
|
||
|
|
}
|
||
|
|
|
||
|
|
private void ClampSelection()
|
||
|
|
{
|
||
|
|
if (_entryIndices.Count == 0)
|
||
|
|
{
|
||
|
|
_selectedIndex = 0;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _entryIndices.Count - 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|