init
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8500d3b307db4440cbb2b15259c11296
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a37259ab32aa640cd81e8293b44864ec
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
|
||||
namespace Luban
|
||||
{
|
||||
public abstract class BeanBase
|
||||
{
|
||||
public abstract int GetTypeId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 961ae68b4acca461b8fed7d37546cc17
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+1568
File diff suppressed because it is too large
Load Diff
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8985430232c694f9082752f8512d3ba7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "Luban.Runtime",
|
||||
"rootNamespace": "Luban",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": true
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3bb549212964b4192b427888ac9382e7
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Luban
|
||||
{
|
||||
public static class StringUtil
|
||||
{
|
||||
public static string ToStr(object o)
|
||||
{
|
||||
return ToStr(o, new StringBuilder());
|
||||
}
|
||||
|
||||
public static string ToStr(object o, StringBuilder sb)
|
||||
{
|
||||
foreach (var p in o.GetType().GetFields())
|
||||
{
|
||||
|
||||
sb.Append($"{p.Name} = {p.GetValue(o)},");
|
||||
}
|
||||
|
||||
foreach (var p in o.GetType().GetProperties())
|
||||
{
|
||||
sb.Append($"{p.Name} = {p.GetValue(o)},");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string ArrayToString<T>(T[] arr)
|
||||
{
|
||||
return "[" + string.Join(",", arr) + "]";
|
||||
}
|
||||
|
||||
|
||||
public static string CollectionToString<T>(IEnumerable<T> arr)
|
||||
{
|
||||
return "[" + string.Join(",", arr) + "]";
|
||||
}
|
||||
|
||||
|
||||
public static string CollectionToString<TK, TV>(IDictionary<TK, TV> dic)
|
||||
{
|
||||
var sb = new StringBuilder('{');
|
||||
foreach (var e in dic)
|
||||
{
|
||||
sb.Append(e.Key).Append(':');
|
||||
sb.Append(e.Value).Append(',');
|
||||
}
|
||||
sb.Append('}');
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4203b9f9688e4f18889305c1e955620
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72fde2baaba154c019124f3a3ae4e9e3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0294fd83b39784653b2c647595f4d138
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class CombatRandinessView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UnityEngine.UI.Text squadMemberText;
|
||||
[SerializeField] public global::UnityEngine.RectTransform characterSlotRoot;
|
||||
[SerializeField] public global::UI.CharacterSlotItem characterSlotTemplate;
|
||||
[SerializeField] public global::UnityEngine.UI.ToggleGroup difficultyTabsToggleGroup;
|
||||
[SerializeField] public global::UnityEngine.UI.InputField seedInput;
|
||||
[SerializeField] public global::UnityEngine.UI.Button randomizeButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Text partyMemberText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text selectMapNumber;
|
||||
[SerializeField] public global::UnityEngine.UI.Text timeLimitText;
|
||||
[SerializeField] public global::UnityEngine.UI.Button beginRunButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Text storageInfoText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c939930432c145ba8e0b087bf96cf67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class CombatReadinessView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UnityEngine.UI.Text squadMemberText;
|
||||
[SerializeField] public global::UnityEngine.RectTransform characterSlotRoot;
|
||||
[SerializeField] public global::UI.CharacterSlotItem characterSlotTemplate;
|
||||
[SerializeField] public global::UnityEngine.UI.ToggleGroup difficultyTabsToggleGroup;
|
||||
[SerializeField] public global::UnityEngine.UI.InputField seedInput;
|
||||
[SerializeField] public global::UnityEngine.UI.Button randomizeButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Text partyMemberText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text selectMapNumber;
|
||||
[SerializeField] public global::UnityEngine.UI.Text timeLimitText;
|
||||
[SerializeField] public global::UnityEngine.UI.Button beginRunButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Text storageInfoText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e844a4c6c1b845babe155b335fd9931
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class InventoryPanelView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UnityEngine.UI.InputField searchInput;
|
||||
[SerializeField] public global::UnityEngine.UI.Button sortButton;
|
||||
[SerializeField] public global::UnityEngine.UI.ScrollRect itemScroll;
|
||||
[SerializeField] public global::UnityEngine.RectTransform warehouseSlotRoot;
|
||||
[SerializeField] public global::UI.WarehouseSlotItem warehouseSlotTemplate;
|
||||
[SerializeField] public global::UnityEngine.UI.Text itemCountText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f585fae70a14d446ba433f3244efded1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class ItemDetailsPanelView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UnityEngine.UI.Image itemDetailIcon;
|
||||
[SerializeField] public global::UnityEngine.UI.Text nameText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text typeText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text hpText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text atkText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text mpText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text matText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text speedText;
|
||||
[SerializeField] public global::UnityEngine.UI.Text stackText;
|
||||
[SerializeField] public global::UnityEngine.UI.Button openLoadoutButton;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4774c8ef6d24f489c8c5858aa014ff13
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class LobbyView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UnityEngine.UI.Button homeButton;
|
||||
[SerializeField] public global::UnityEngine.RectTransform selectionMarkerObject;
|
||||
[SerializeField] public global::UnityEngine.UI.Button warehouseButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Button loadoutButton;
|
||||
[SerializeField] public global::UI.CombatRandinessView combatRandinessView;
|
||||
[SerializeField] public global::UI.WarehouseView warehouseView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d9bc156ee806453a8f2ddd99b1dab0c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class MainWarehouseView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UnityEngine.UI.Button homeButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Button warehouseButton;
|
||||
[SerializeField] public global::UnityEngine.UI.Button loadoutButton;
|
||||
[SerializeField] public global::UnityEngine.UI.InputField searchInput;
|
||||
[SerializeField] public global::UnityEngine.UI.Button sortButton;
|
||||
[SerializeField] public global::UnityEngine.UI.ScrollRect itemScroll;
|
||||
[SerializeField] public global::UnityEngine.RectTransform warehouseSlotRoot;
|
||||
[SerializeField] public global::UI.WarehouseSlotItem warehouseSlotTemplate;
|
||||
[SerializeField] public global::UnityEngine.UI.Text itemCountText;
|
||||
[SerializeField] public global::UnityEngine.UI.Button openLoadoutButton;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f169da115e10a47e4b0b3bfefaff0d71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
// <auto-generated />
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public partial class WarehouseView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public global::UI.InventoryPanelView inventoryPanelView;
|
||||
[SerializeField] public global::UI.ItemDetailsPanelView itemDetailsPanelView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b37653f27a37b493691e4a8347d826e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d1792508be4541c49721d77aaa16dce
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class CharacterSlotItem : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Image bg;
|
||||
[SerializeField] private Image icon;
|
||||
[SerializeField] private Text characterName;
|
||||
[SerializeField] private Text hpText;
|
||||
[SerializeField] private Text mpText;
|
||||
[SerializeField] private Text speedText;
|
||||
[SerializeField] private Text atkText;
|
||||
[SerializeField] private Text matText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d3418d26a66340028b5d353f0077c1c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
public class WarehouseSlotItem : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Image bg;
|
||||
[SerializeField] private Button button;
|
||||
[SerializeField] private Image icon;
|
||||
[SerializeField] private Image rarity;
|
||||
[SerializeField] private Text quantityText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ec7b73a5570746109f8d90e913c60fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dd243b8051ec4d7596ba47b4a079669
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[ExecuteAlways]
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class UISerializationItem : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class ComponentReference
|
||||
{
|
||||
[SerializeField] private Component component;
|
||||
[SerializeField] private bool generateReference;
|
||||
[SerializeField] private string variableName;
|
||||
|
||||
public Component Component => component;
|
||||
public bool GenerateReference => generateReference;
|
||||
public string VariableName => variableName;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal ComponentReference(Component target, string defaultVariableName)
|
||||
{
|
||||
component = target;
|
||||
generateReference = false;
|
||||
variableName = defaultVariableName;
|
||||
}
|
||||
|
||||
internal void Configure(bool shouldGenerate, string generatedVariableName)
|
||||
{
|
||||
generateReference = shouldGenerate;
|
||||
variableName = generatedVariableName;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private List<ComponentReference> componentReferences = new List<ComponentReference>();
|
||||
|
||||
public IReadOnlyList<ComponentReference> ComponentReferences => componentReferences;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private bool refreshQueued;
|
||||
|
||||
public bool RefreshComponents()
|
||||
{
|
||||
Component[] attachedComponents = GetComponents<Component>();
|
||||
var next = new List<ComponentReference>(attachedComponents.Length);
|
||||
|
||||
for (int i = 0; i < attachedComponents.Length; i++)
|
||||
{
|
||||
Component attached = attachedComponents[i];
|
||||
if (attached == null || attached == this || attached is UISerializationRoot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ComponentReference existing = FindReference(attached);
|
||||
next.Add(existing ?? new ComponentReference(attached, CreateDefaultVariableName(gameObject, attached)));
|
||||
}
|
||||
|
||||
if (HasSameComponents(next))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
componentReferences = next;
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetReference(Component component, bool shouldGenerate, string variableName)
|
||||
{
|
||||
if (component == null || component.gameObject != gameObject)
|
||||
{
|
||||
throw new ArgumentException("The component must be attached to the same GameObject as the serialization item.", nameof(component));
|
||||
}
|
||||
|
||||
RefreshComponents();
|
||||
ComponentReference reference = FindReference(component);
|
||||
if (reference == null)
|
||||
{
|
||||
throw new InvalidOperationException("The component is not available for UI serialization.");
|
||||
}
|
||||
|
||||
string normalizedName = variableName == null ? string.Empty : variableName.Trim();
|
||||
if (reference.GenerateReference == shouldGenerate && reference.VariableName == normalizedName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
reference.Configure(shouldGenerate, normalizedName);
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
NotifyRoot();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string CreateDefaultVariableName(GameObject owner, Component component)
|
||||
{
|
||||
string ownerName = ToCamelIdentifier(owner == null ? "uiItem" : owner.name);
|
||||
string typeName = component == null ? "Component" : component.GetType().Name;
|
||||
|
||||
if (component is RectTransform)
|
||||
{
|
||||
typeName = "RectTransform";
|
||||
}
|
||||
|
||||
if (ownerName.EndsWith(typeName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ownerName;
|
||||
}
|
||||
|
||||
return ownerName + typeName;
|
||||
}
|
||||
|
||||
internal void QueueRefresh()
|
||||
{
|
||||
if (refreshQueued || Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
refreshQueued = true;
|
||||
UnityEditor.EditorApplication.delayCall += RefreshDelayed;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
RefreshComponents();
|
||||
NotifyRoot();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
QueueRefresh();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
QueueRefresh();
|
||||
}
|
||||
|
||||
private void RefreshDelayed()
|
||||
{
|
||||
refreshQueued = false;
|
||||
if (this == null || Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshComponents();
|
||||
NotifyRoot();
|
||||
}
|
||||
|
||||
private void NotifyRoot()
|
||||
{
|
||||
UISerializationRoot root = GetComponentInParent<UISerializationRoot>(true);
|
||||
if (root != null)
|
||||
{
|
||||
root.QueueRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
private ComponentReference FindReference(Component component)
|
||||
{
|
||||
for (int i = 0; i < componentReferences.Count; i++)
|
||||
{
|
||||
ComponentReference reference = componentReferences[i];
|
||||
if (reference != null && reference.Component == component)
|
||||
{
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool HasSameComponents(List<ComponentReference> next)
|
||||
{
|
||||
if (componentReferences.Count != next.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < next.Count; i++)
|
||||
{
|
||||
if (componentReferences[i] == null || componentReferences[i].Component != next[i].Component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string ToCamelIdentifier(string value)
|
||||
{
|
||||
var builder = new StringBuilder(value.Length + 8);
|
||||
bool capitalizeNext = false;
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
char current = value[i];
|
||||
if (!char.IsLetterOrDigit(current) && current != '_')
|
||||
{
|
||||
capitalizeNext = builder.Length > 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (builder.Length == 0)
|
||||
{
|
||||
if (char.IsDigit(current))
|
||||
{
|
||||
builder.Append('_');
|
||||
}
|
||||
builder.Append(char.ToLowerInvariant(current));
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Append(capitalizeNext ? char.ToUpperInvariant(current) : current);
|
||||
capitalizeNext = false;
|
||||
}
|
||||
|
||||
return builder.Length == 0 ? "uiItem" : builder.ToString();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbaa237e23f7d4d3f85f73e0acd7eaec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,308 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
[ExecuteAlways]
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class UISerializationRoot : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class NestedViewReference
|
||||
{
|
||||
[SerializeField] private UISerializationRoot root;
|
||||
[SerializeField] private bool generateReference;
|
||||
[SerializeField] private string variableName;
|
||||
|
||||
public UISerializationRoot Root => root;
|
||||
public bool GenerateReference => generateReference;
|
||||
public string VariableName => variableName;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal NestedViewReference(UISerializationRoot nestedRoot, string defaultVariableName)
|
||||
{
|
||||
root = nestedRoot;
|
||||
generateReference = true;
|
||||
variableName = defaultVariableName;
|
||||
}
|
||||
|
||||
internal void Configure(bool shouldGenerate, string generatedVariableName)
|
||||
{
|
||||
generateReference = shouldGenerate;
|
||||
variableName = generatedVariableName;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private List<UISerializationItem> serializationItems = new List<UISerializationItem>();
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private List<NestedViewReference> nestedViewReferences = new List<NestedViewReference>();
|
||||
|
||||
public IReadOnlyList<UISerializationItem> SerializationItems => serializationItems;
|
||||
public IReadOnlyList<NestedViewReference> NestedViewReferences => nestedViewReferences;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private bool refreshQueued;
|
||||
|
||||
public bool RefreshItems()
|
||||
{
|
||||
UISerializationItem[] allItems = GetComponentsInChildren<UISerializationItem>(true);
|
||||
var ownedItems = new List<UISerializationItem>(allItems.Length);
|
||||
for (int i = 0; i < allItems.Length; i++)
|
||||
{
|
||||
UISerializationItem item = allItems[i];
|
||||
if (item == null || FindNearestRoot(item.transform) != this)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
item.RefreshComponents();
|
||||
ownedItems.Add(item);
|
||||
}
|
||||
|
||||
UISerializationRoot[] allRoots = GetComponentsInChildren<UISerializationRoot>(true);
|
||||
var directNestedRoots = new List<UISerializationRoot>(allRoots.Length);
|
||||
for (int i = 0; i < allRoots.Length; i++)
|
||||
{
|
||||
UISerializationRoot candidate = allRoots[i];
|
||||
if (candidate != null && candidate != this && FindNearestParentRoot(candidate.transform) == this)
|
||||
{
|
||||
directNestedRoots.Add(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
bool itemsChanged = !HasSameItems(ownedItems);
|
||||
bool nestedViewsChanged = !HasSameNestedViews(directNestedRoots);
|
||||
if (!itemsChanged && !nestedViewsChanged)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itemsChanged)
|
||||
{
|
||||
serializationItems.Clear();
|
||||
serializationItems.AddRange(ownedItems);
|
||||
}
|
||||
|
||||
if (nestedViewsChanged)
|
||||
{
|
||||
var next = new List<NestedViewReference>(directNestedRoots.Count);
|
||||
for (int i = 0; i < directNestedRoots.Count; i++)
|
||||
{
|
||||
UISerializationRoot nestedRoot = directNestedRoots[i];
|
||||
NestedViewReference existing = FindNestedView(nestedRoot);
|
||||
next.Add(existing ?? new NestedViewReference(nestedRoot, CreateDefaultNestedViewVariableName(nestedRoot)));
|
||||
}
|
||||
|
||||
nestedViewReferences = next;
|
||||
}
|
||||
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetNestedViewReference(UISerializationRoot nestedRoot, bool shouldGenerate, string variableName)
|
||||
{
|
||||
if (nestedRoot == null || FindNearestParentRoot(nestedRoot.transform) != this)
|
||||
{
|
||||
throw new ArgumentException("The nested root must be directly owned by this serialization root.", nameof(nestedRoot));
|
||||
}
|
||||
|
||||
RefreshItems();
|
||||
NestedViewReference reference = FindNestedView(nestedRoot);
|
||||
if (reference == null)
|
||||
{
|
||||
throw new InvalidOperationException("The nested root is not registered.");
|
||||
}
|
||||
|
||||
string normalizedName = variableName == null ? string.Empty : variableName.Trim();
|
||||
if (reference.GenerateReference == shouldGenerate && reference.VariableName == normalizedName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
reference.Configure(shouldGenerate, normalizedName);
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string CreateDefaultNestedViewVariableName(UISerializationRoot nestedRoot)
|
||||
{
|
||||
string sourceName = nestedRoot == null ? "nested" : nestedRoot.gameObject.name.Replace("(Clone)", string.Empty).Trim();
|
||||
if (sourceName.EndsWith("UI", StringComparison.Ordinal) && sourceName.Length > 2)
|
||||
{
|
||||
sourceName = sourceName.Substring(0, sourceName.Length - 2);
|
||||
}
|
||||
|
||||
string identifier = ToPascalIdentifier(sourceName);
|
||||
if (string.IsNullOrEmpty(identifier))
|
||||
{
|
||||
identifier = "Nested";
|
||||
}
|
||||
|
||||
return char.ToLowerInvariant(identifier[0]) + identifier.Substring(1) + "View";
|
||||
}
|
||||
|
||||
internal void QueueRefresh()
|
||||
{
|
||||
if (refreshQueued || Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
refreshQueued = true;
|
||||
UnityEditor.EditorApplication.delayCall += RefreshDelayed;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
RefreshItems();
|
||||
NotifyParentRoot();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
QueueRefresh();
|
||||
NotifyParentRoot();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
QueueRefresh();
|
||||
NotifyParentRoot();
|
||||
}
|
||||
|
||||
private void OnTransformChildrenChanged()
|
||||
{
|
||||
QueueRefresh();
|
||||
}
|
||||
|
||||
private void OnTransformParentChanged()
|
||||
{
|
||||
QueueRefresh();
|
||||
NotifyParentRoot();
|
||||
}
|
||||
|
||||
private void RefreshDelayed()
|
||||
{
|
||||
refreshQueued = false;
|
||||
if (this == null || Application.isPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshItems();
|
||||
}
|
||||
|
||||
private bool HasSameItems(List<UISerializationItem> found)
|
||||
{
|
||||
if (serializationItems.Count != found.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < found.Count; i++)
|
||||
{
|
||||
if (serializationItems[i] != found[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HasSameNestedViews(List<UISerializationRoot> found)
|
||||
{
|
||||
if (nestedViewReferences.Count != found.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < found.Count; i++)
|
||||
{
|
||||
if (nestedViewReferences[i] == null || nestedViewReferences[i].Root != found[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private NestedViewReference FindNestedView(UISerializationRoot nestedRoot)
|
||||
{
|
||||
for (int i = 0; i < nestedViewReferences.Count; i++)
|
||||
{
|
||||
NestedViewReference reference = nestedViewReferences[i];
|
||||
if (reference != null && reference.Root == nestedRoot)
|
||||
{
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void NotifyParentRoot()
|
||||
{
|
||||
UISerializationRoot parentRoot = FindNearestParentRoot(transform);
|
||||
if (parentRoot != null)
|
||||
{
|
||||
parentRoot.QueueRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
private static UISerializationRoot FindNearestRoot(Transform target)
|
||||
{
|
||||
Transform current = target;
|
||||
while (current != null)
|
||||
{
|
||||
UISerializationRoot root = current.GetComponent<UISerializationRoot>();
|
||||
if (root != null)
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static UISerializationRoot FindNearestParentRoot(Transform target)
|
||||
{
|
||||
return target == null ? null : FindNearestRoot(target.parent);
|
||||
}
|
||||
|
||||
private static string ToPascalIdentifier(string value)
|
||||
{
|
||||
var builder = new StringBuilder(value.Length + 8);
|
||||
bool capitalizeNext = true;
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
char current = value[i];
|
||||
if (!char.IsLetterOrDigit(current) && current != '_')
|
||||
{
|
||||
capitalizeNext = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (builder.Length == 0 && char.IsDigit(current))
|
||||
{
|
||||
builder.Append('_');
|
||||
}
|
||||
|
||||
builder.Append(capitalizeNext ? char.ToUpperInvariant(current) : current);
|
||||
capitalizeNext = false;
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 335062b0d81ae40f49c923ef4bf19dd7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user