迁移剩下的 UI 到 Serialization 方式

This commit is contained in:
2026-09-14 17:19:31 +08:00
parent 091a29db63
commit b628a8537c
107 changed files with 4147 additions and 3680 deletions
@@ -0,0 +1,3 @@
 HUDHpText {0} / {1}
HUDExpTextLv.{0} HUDCoinText <sprite name="coin" index=0> {0}HUDCPUTimeCostTextCPU Frame: {0:F2} msHUDEnemyCountText
Enemy: {0}LevelUpRefreshCostText(刷新 -{0} <sprite name="coin" index=0>␍ShopTitleText商店 (Lv.{0})ShopContinueButtonText继续 (Lv.{0})ShopPlayerCoinText<sprite name="coin"> {0}ShopRefreshCostText 刷新 -{0} <sprite name="coin">WeaponListTitle武器 ({0}/{1})␍PropListTitle 道具 ({0})ShopGoodsCostText {0} <sprite name="coin" index=0>TooltipRecycleButtonText'出售 {0} <sprite name="coin" index=0>
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 09ee293d7e6c7b5478b17ac940bcfb8e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,58 @@
[
{
"name": "HUDHpText",
"format": "{0} / {1}"
},
{
"name": "HUDExpText",
"format": "Lv.{0}"
},
{
"name": "HUDCoinText",
"format": "<sprite name=\"coin\" index=0> {0}"
},
{
"name": "HUDCPUTimeCostText",
"format": "CPU Frame: {0:F2} ms"
},
{
"name": "HUDEnemyCountText",
"format": "Enemy: {0}"
},
{
"name": "LevelUpRefreshCostText",
"format": "刷新 -{0} <sprite name=\"coin\" index=0>"
},
{
"name": "ShopTitleText",
"format": "商店 (Lv.{0})"
},
{
"name": "ShopContinueButtonText",
"format": "继续 (Lv.{0})"
},
{
"name": "ShopPlayerCoinText",
"format": "<sprite name=\"coin\"> {0}"
},
{
"name": "ShopRefreshCostText",
"format": "刷新 -{0} <sprite name=\"coin\">"
},
{
"name": "WeaponListTitle",
"format": "武器 ({0}/{1})"
},
{
"name": "PropListTitle",
"format": "道具 ({0})"
},
{
"name": "ShopGoodsCostText",
"format": "{0} <sprite name=\"coin\" index=0>"
},
{
"name": "TooltipRecycleButtonText",
"format": "出售 {0} <sprite name=\"coin\" index=0>"
}
]
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5c1d742cd5d626e4e867ec0ca8482db7
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace SepCore.Definition
{
public sealed partial class FormatText : Luban.BeanBase
{
public FormatText(ByteBuf _buf)
{
Name = _buf.ReadString();
Format = _buf.ReadString();
}
public static FormatText DeserializeFormatText(ByteBuf _buf)
{
return new FormatText(_buf);
}
/// <summary>
/// 文本名
/// </summary>
public readonly string Name;
/// <summary>
/// 格式化字符串
/// </summary>
public readonly string Format;
public const int __ID__ = -1977697820;
public override int GetTypeId() => __ID__;
public void ResolveRef(Tables tables)
{
}
public override string ToString()
{
return "{ "
+ "name:" + Name + ","
+ "format:" + Format + ","
+ "}";
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: f21ab051c635de04998b80804d9bafe5 guid: 721766cc68542b640a2119ab0c73a833
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
@@ -21,6 +21,7 @@ public partial class Tables
/// 实体配置 /// 实体配置
/// </summary> /// </summary>
public TbEntityConfig TbEntityConfig {get; } public TbEntityConfig TbEntityConfig {get; }
public TbFormatText TbFormatText {get; }
/// <summary> /// <summary>
/// 全局零散配置(单例) /// 全局零散配置(单例)
/// </summary> /// </summary>
@@ -65,6 +66,7 @@ public partial class Tables
{ {
TbEnemyConfig = new TbEnemyConfig(loader("tbenemyconfig")); TbEnemyConfig = new TbEnemyConfig(loader("tbenemyconfig"));
TbEntityConfig = new TbEntityConfig(loader("tbentityconfig")); TbEntityConfig = new TbEntityConfig(loader("tbentityconfig"));
TbFormatText = new TbFormatText(loader("tbformattext"));
TbGlobalConfig = new TbGlobalConfig(loader("tbglobalconfig")); TbGlobalConfig = new TbGlobalConfig(loader("tbglobalconfig"));
TbGoodsConfig = new TbGoodsConfig(loader("tbgoodsconfig")); TbGoodsConfig = new TbGoodsConfig(loader("tbgoodsconfig"));
TbLevelConfig = new TbLevelConfig(loader("tblevelconfig")); TbLevelConfig = new TbLevelConfig(loader("tblevelconfig"));
@@ -87,6 +89,7 @@ public partial class Tables
{ {
TbEnemyConfig.ResolveRef(this); TbEnemyConfig.ResolveRef(this);
TbEntityConfig.ResolveRef(this); TbEntityConfig.ResolveRef(this);
TbFormatText.ResolveRef(this);
TbGlobalConfig.ResolveRef(this); TbGlobalConfig.ResolveRef(this);
TbGoodsConfig.ResolveRef(this); TbGoodsConfig.ResolveRef(this);
TbLevelConfig.ResolveRef(this); TbLevelConfig.ResolveRef(this);
@@ -0,0 +1,52 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Luban;
namespace SepCore.Definition
{
public partial class TbFormatText
{
private readonly System.Collections.Generic.Dictionary<string, FormatText> _dataMap;
private readonly System.Collections.Generic.List<FormatText> _dataList;
public TbFormatText(ByteBuf _buf)
{
_dataMap = new System.Collections.Generic.Dictionary<string, FormatText>();
_dataList = new System.Collections.Generic.List<FormatText>();
for(int n = _buf.ReadSize() ; n > 0 ; --n)
{
FormatText _v;
_v = FormatText.DeserializeFormatText(_buf);
_dataList.Add(_v);
_dataMap.Add(_v.Name, _v);
}
}
public System.Collections.Generic.Dictionary<string, FormatText> DataMap => _dataMap;
public System.Collections.Generic.List<FormatText> DataList => _dataList;
public FormatText GetOrDefault(string key) => _dataMap.TryGetValue(key, out var v) ? v : null;
public FormatText Get(string key) => _dataMap[key];
public FormatText this[string key] => _dataMap[key];
public void ResolveRef(Tables tables)
{
foreach(var _v in _dataList)
{
_v.ResolveRef(tables);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8574165ef5ddc674fb6c69eaab38a63e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -72,7 +72,6 @@ namespace SepCore.Editor
private sealed class Binding private sealed class Binding
{ {
public Component component; public Component component;
public UISerializationRoot nestedRoot;
public string variableName; public string variableName;
public string csharpTypeName; public string csharpTypeName;
} }
@@ -129,7 +128,7 @@ namespace SepCore.Editor
List<UISerializationRoot> generationRoots = CollectGenerationRoots(root); List<UISerializationRoot> generationRoots = CollectGenerationRoots(root);
List<GenerationUnit> units = BuildGenerationUnits(generationRoots); List<GenerationUnit> units = BuildGenerationUnits(generationRoots);
GenerationUnit primaryUnit = units[units.Count - 1]; GenerationUnit primaryUnit = units[0];
List<string> changedExistingFiles = units List<string> changedExistingFiles = units
.Where(unit => unit.SourceChanged) .Where(unit => unit.SourceChanged)
@@ -382,35 +381,8 @@ namespace SepCore.Editor
private static List<UISerializationRoot> CollectGenerationRoots(UISerializationRoot selectedRoot) private static List<UISerializationRoot> CollectGenerationRoots(UISerializationRoot selectedRoot)
{ {
bool persistentContext = EditorUtility.IsPersistent(selectedRoot); bool persistentContext = EditorUtility.IsPersistent(selectedRoot);
var result = new List<UISerializationRoot>(); UISerializationRoot generationRoot = GetCanonicalRoot(selectedRoot, persistentContext);
var visited = new HashSet<UISerializationRoot>(); return new List<UISerializationRoot> { generationRoot };
CollectGenerationRootsRecursive(selectedRoot, persistentContext, visited, result);
return result;
}
private static void CollectGenerationRootsRecursive(
UISerializationRoot current,
bool persistentContext,
HashSet<UISerializationRoot> visited,
List<UISerializationRoot> result)
{
current = GetCanonicalRoot(current, persistentContext);
if (current == null || !visited.Add(current))
{
return;
}
current.RefreshItems();
for (int i = 0; i < current.NestedFormReferences.Count; i++)
{
UISerializationRoot nestedRoot = current.NestedFormReferences[i].Root;
if (nestedRoot != null)
{
CollectGenerationRootsRecursive(nestedRoot, persistentContext, visited, result);
}
}
result.Add(current);
} }
private static UISerializationRoot GetCanonicalRoot(UISerializationRoot root, bool persistentContext) private static UISerializationRoot GetCanonicalRoot(UISerializationRoot root, bool persistentContext)
@@ -533,18 +505,51 @@ namespace SepCore.Editor
throw new InvalidOperationException("A nested UI Form reference is missing below " + GetHierarchyPath(root.transform) + "."); throw new InvalidOperationException("A nested UI Form reference is missing below " + GetHierarchyPath(root.transform) + ".");
} }
UGuiForm nestedForm = FindNestedForm(nestedRoot, out string nestedFormError);
if (nestedForm == null)
{
throw new InvalidOperationException(nestedFormError);
}
string variableName = NormalizeAndValidateVariableName(reference.VariableName, nestedRoot.transform, names); string variableName = NormalizeAndValidateVariableName(reference.VariableName, nestedRoot.transform, names);
bindings.Add(new Binding bindings.Add(new Binding
{ {
nestedRoot = nestedRoot, component = nestedForm,
variableName = variableName, variableName = variableName,
csharpTypeName = "global::" + GeneratedNamespace + "." + GetFormClassName(nestedRoot) csharpTypeName = GetCSharpTypeName(nestedForm.GetType())
}); });
} }
return bindings; return bindings;
} }
public static UGuiForm FindNestedForm(UISerializationRoot nestedRoot, out string error)
{
error = null;
if (nestedRoot == null)
{
error = "The nested UI root is missing.";
return null;
}
UGuiForm[] forms = nestedRoot.GetComponents<UGuiForm>();
if (forms.Length == 0)
{
error = "Nested UI root '" + GetHierarchyPath(nestedRoot.transform) +
"' does not have a UGuiForm component. Generate its View & Form scripts first.";
return null;
}
if (forms.Length > 1)
{
error = "Nested UI root '" + GetHierarchyPath(nestedRoot.transform) +
"' has multiple UGuiForm components.";
return null;
}
return forms[0];
}
private static string NormalizeAndValidateVariableName(string value, Transform owner, HashSet<string> names) private static string NormalizeAndValidateVariableName(string value, Transform owner, HashSet<string> names)
{ {
string variableName = value == null ? string.Empty : value.Trim(); string variableName = value == null ? string.Empty : value.Trim();
@@ -755,26 +760,7 @@ namespace SepCore.Editor
throw new InvalidOperationException("Generated field was not found: " + binding.variableName + "."); throw new InvalidOperationException("Generated field was not found: " + binding.variableName + ".");
} }
UnityEngine.Object target = binding.component; property.objectReferenceValue = binding.component;
if (binding.nestedRoot != null)
{
string nestedFormFullName = GeneratedNamespace + "." + GetFormClassName(binding.nestedRoot);
Type nestedFormType = FindGeneratedType(nestedFormFullName);
if (nestedFormType == null)
{
throw new InvalidOperationException("Nested UI form type was not found: " + nestedFormFullName + ".");
}
target = binding.nestedRoot.GetComponent(nestedFormType);
if (target == null)
{
throw new InvalidOperationException(
"Nested UI root '" + GetHierarchyPath(binding.nestedRoot.transform) +
"' does not have its generated Form component '" + nestedFormFullName + "'.");
}
}
property.objectReferenceValue = target;
} }
serializedView.ApplyModifiedProperties(); serializedView.ApplyModifiedProperties();
@@ -107,7 +107,15 @@ namespace SepCore.Editor
if (nestedRoot != null) if (nestedRoot != null)
{ {
EditorGUILayout.LabelField("Form Class", UIAssetsTools.GetFormClassName(nestedRoot)); UGuiForm nestedForm = UIAssetsTools.FindNestedForm(nestedRoot, out string nestedFormError);
if (nestedForm != null)
{
EditorGUILayout.LabelField("Form Class", nestedForm.GetType().FullName);
}
else
{
EditorGUILayout.HelpBox(nestedFormError, MessageType.Error);
}
} }
if (generate.boolValue) if (generate.boolValue)
@@ -0,0 +1,41 @@
using SepCore.Definition;
using TMPro;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
/// <summary>
/// 使用 Luban 格式化文本表(TbFormatText)驱动 TextMeshProUGUI 的组件。
/// 在 Inspector 上填写 Key,调用 Set 传入格式化参数即可更新文本。
/// </summary>
[RequireComponent(typeof(TextMeshProUGUI))]
public class FormatTextUI : MonoBehaviour
{
[SerializeField] private string key;
private TextMeshProUGUI _text;
private void Awake()
{
_text = GetComponent<TextMeshProUGUI>();
}
public void Set(params object[] args)
{
FormatText format = GameEntry.Luban.Tables.TbFormatText.GetOrDefault(key);
if (format == null)
{
Log.Warning("Can not find format text '{0}'.", key);
return;
}
_text.SetText(string.Format(format.Format, args));
}
public void Clear()
{
_text.SetText(string.Empty);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2efdcd06cdaa830448f76b22ea7c98fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 16815ca7d82e7ea4c91dd017189eeacb guid: 0a0edeeb11ca93846b60f6fbb75452a9
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
@@ -11,18 +11,19 @@ namespace SepCore.UI
[SerializeField] private IconArea _iconArea; [SerializeField] private IconArea _iconArea;
[SerializeField] private RectTransform _itemRect; [SerializeField] private RectTransform _itemRect;
[SerializeField] private CommonButton _button;
private DisplayItemContext _context; private DisplayItemContext _context;
private int _index = -1; private int _index = -1;
public void SetIndex(int index) private bool _listenersBound;
{
_index = index;
}
public async UniTaskVoid OnInit(DisplayItemContext context, int index) public async UniTaskVoid OnInit(DisplayItemContext context, int index)
{ {
EnsureListeners();
_context = context; _context = context;
_index = index; _index = index;
@@ -38,7 +39,22 @@ namespace SepCore.UI
_iconArea.OnReset(); _iconArea.OnReset();
} }
public void OnItemInfoShow() private void EnsureListeners()
{
if (_listenersBound)
{
return;
}
_listenersBound = true;
CommonButton button = GetComponent<CommonButton>();
button.onClick.AddListener(OnItemInfoLock);
button.RegisterPointerEnterAction(OnItemInfoShow);
button.RegisterPointerExitAction(OnItemInfoHide);
}
private void OnItemInfoShow()
{ {
if (_index < 0) return; if (_index < 0) return;
@@ -51,14 +67,14 @@ namespace SepCore.UI
GameEntry.Event.Fire(this, DisplayItemHoverEventArgs.Create(_index, _context.IsWeapon, targetPos)); GameEntry.Event.Fire(this, DisplayItemHoverEventArgs.Create(_index, _context.IsWeapon, targetPos));
} }
public void OnItemInfoLock() private void OnItemInfoLock()
{ {
GameEntry.Event.Fire(this, DisplayItemLockEventArgs.Create()); GameEntry.Event.Fire(this, DisplayItemLockEventArgs.Create());
} }
public void OnItemInfoHide() private void OnItemInfoHide()
{ {
GameEntry.Event.Fire(this, DisplayItemHideEventArgs.Create()); GameEntry.Event.Fire(this, DisplayItemHideEventArgs.Create());
} }
} }
} }
@@ -0,0 +1,9 @@
namespace SepCore.UI
{
public class DisplayListContext : UIContext
{
public int CurrentCount;
public int MaxCount = -1;
public DisplayItemContext[] ItemContexts;
}
}
@@ -0,0 +1,51 @@
using System.Collections.Generic;
using UnityEngine;
namespace SepCore.UI
{
public partial class DisplayListForm
{
private readonly List<DisplayItem> _displayItems = new List<DisplayItem>();
public void OnInit(DisplayListContext context)
{
View.titleFormatText.Set(context.CurrentCount, context.MaxCount);
int targetCount = Mathf.Min(context.CurrentCount, context.ItemContexts.Length);
EnsureItemCount(targetCount);
for (int i = 0; i < _displayItems.Count; i++)
{
DisplayItem item = _displayItems[i];
if (i < targetCount)
{
item.OnInit(context.ItemContexts[i], i).Forget();
item.gameObject.SetActive(true);
}
else
{
item.OnReset();
item.gameObject.SetActive(false);
}
}
}
public void OnReset()
{
for (int i = 0; i < _displayItems.Count; i++)
{
_displayItems[i].OnReset();
_displayItems[i].gameObject.SetActive(false);
}
}
private void EnsureItemCount(int count)
{
while (_displayItems.Count < count)
{
DisplayItem item = Instantiate(View.displayItemTemplate, View.listRoot.transform);
_displayItems.Add(item);
}
}
}
}
@@ -0,0 +1,13 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class DisplayListForm : UGuiForm
{
[SerializeField] private DisplayListView _view = null;
public DisplayListView View => _view;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 220e0137e2c60eb4084e50234225dd50
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,13 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class DisplayListView : MonoBehaviour
{
[SerializeField] public global::SepCore.UI.FormatTextUI titleFormatText;
[SerializeField] public global::UnityEngine.UI.GridLayoutGroup listRoot;
[SerializeField] public global::SepCore.UI.DisplayItem displayItemTemplate;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9eb9bf8c92339346b767aa476f14f94
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 5d21ab27094da2548a00119313150780 guid: ec716511ca2cd8043bff922575851a1b
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
@@ -2,47 +2,29 @@ using System.Collections;
using SepCore.Event; using SepCore.Event;
using GameFramework.Event; using GameFramework.Event;
using SepCore.EnemyManager; using SepCore.EnemyManager;
using TMPro;
using UnityEngine; using UnityEngine;
using Unity.Profiling; using Unity.Profiling;
using UnityEngine.UI;
namespace SepCore.UI namespace SepCore.UI
{ {
public class HudForm : UGuiForm public partial class HudForm : UGuiForm
{ {
[SerializeField] private float _sliderFadeDuration = 0.5f; [SerializeField] private float _sliderFadeDuration = 0.5f;
[SerializeField] private Slider _hpSlider;
[SerializeField] private TMP_Text _hpText;
private float _currentHpPercent = 0; private float _currentHpPercent = 0;
private Coroutine _hpSliderFadeCoroutine; private Coroutine _hpSliderFadeCoroutine;
[SerializeField] private Slider _expSlider;
private float _currentExpPercent = 0; private float _currentExpPercent = 0;
private Coroutine _expSliderFadeCoroutine; private Coroutine _expSliderFadeCoroutine;
[SerializeField] private TMP_Text _expText;
private int _playerCurrentLevel = 1; private int _playerCurrentLevel = 1;
[SerializeField] private TMP_Text _coinText;
private int _currentCoin = 0; private int _currentCoin = 0;
[SerializeField] private TMP_Text _levelTimeLeftText;
private int _currentTimeLeft = 0; private int _currentTimeLeft = 0;
[SerializeField] private TMP_Text _enemyCountText;
private EnemyManagerComponent _enemy; private EnemyManagerComponent _enemy;
[SerializeField] private GameObject _movePromptRoot;
[SerializeField] private TMP_Text _movePromptText;
[SerializeField] private TMP_Text _cpuTimeCostText;
[SerializeField] private float _performanceStatsRefreshInterval = 0.2f; [SerializeField] private float _performanceStatsRefreshInterval = 0.2f;
private ProfilerRecorder _cpuTimeRecorder; private ProfilerRecorder _cpuTimeRecorder;
@@ -57,8 +39,8 @@ namespace SepCore.UI
public void RefreshMovePrompt(string prompt) public void RefreshMovePrompt(string prompt)
{ {
bool visible = !string.IsNullOrEmpty(prompt); bool visible = !string.IsNullOrEmpty(prompt);
_movePromptRoot.SetActive(visible); View.inputPromptObject.gameObject.SetActive(visible);
_movePromptText.text = prompt; View.inputPromptText.text = prompt;
} }
#region FSM #region FSM
@@ -145,15 +127,7 @@ namespace SepCore.UI
protected override void OnUpdate(float elapseSeconds, float realElapseSeconds) protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{ {
base.OnUpdate(elapseSeconds, realElapseSeconds); base.OnUpdate(elapseSeconds, realElapseSeconds);
if (_enemy == null) View.enemyCountFormatText.Set(_enemy.CurrentEnemyCount);
{
_enemy = GameEntry.EnemyManager;
}
if (_enemy != null)
{
_enemyCountText.text = $"Enemy: {_enemy.CurrentEnemyCount}";
}
} }
#endregion #endregion
@@ -179,14 +153,13 @@ namespace SepCore.UI
if (!hasCpuFrame) if (!hasCpuFrame)
{ {
_cpuTimeCostText.text = View.cpuTimeCostFormatText.Set(-1);
"CPU Frame: -- ms\nSimulation: -- ms\nJob Wait: -- ms";
return; return;
} }
float cpuFrameMilliseconds = cpuFrameNanoseconds / 1_000_000f; float cpuFrameMilliseconds = cpuFrameNanoseconds / 1_000_000f;
_cpuTimeCostText.SetText("CPU Frame: {0:2} ms",cpuFrameMilliseconds); View.cpuTimeCostFormatText.Set(cpuFrameMilliseconds);
} }
private static bool TryGetLastValue(ProfilerRecorder recorder, out long value) private static bool TryGetLastValue(ProfilerRecorder recorder, out long value)
@@ -207,7 +180,7 @@ namespace SepCore.UI
{ {
if (!(e is PlayerHealthChangeEventArgs args)) return; if (!(e is PlayerHealthChangeEventArgs args)) return;
_hpText.text = $"{args.CurrentHealth}/{args.MaxHealth}"; View.hpFormatText.Set(args.CurrentHealth, args.MaxHealth);
float percent = (float)args.CurrentHealth / args.MaxHealth; float percent = (float)args.CurrentHealth / args.MaxHealth;
if (Mathf.Approximately(_currentHpPercent, percent)) return; if (Mathf.Approximately(_currentHpPercent, percent)) return;
@@ -215,7 +188,7 @@ namespace SepCore.UI
_currentHpPercent = percent; _currentHpPercent = percent;
if (_hpSliderFadeCoroutine != null) StopCoroutine(_hpSliderFadeCoroutine); if (_hpSliderFadeCoroutine != null) StopCoroutine(_hpSliderFadeCoroutine);
_hpSliderFadeCoroutine = StartCoroutine(_hpSlider.SmoothValue(percent, _sliderFadeDuration)); _hpSliderFadeCoroutine = StartCoroutine(View.hpSlider.SmoothValue(percent, _sliderFadeDuration));
} }
private void PlayerExpChange(object sender, GameEventArgs e) private void PlayerExpChange(object sender, GameEventArgs e)
@@ -227,7 +200,7 @@ namespace SepCore.UI
_currentExpPercent = percent; _currentExpPercent = percent;
if (_expSliderFadeCoroutine != null) StopCoroutine(_expSliderFadeCoroutine); if (_expSliderFadeCoroutine != null) StopCoroutine(_expSliderFadeCoroutine);
_expSliderFadeCoroutine = StartCoroutine(_expSlider.SmoothValue(percent, _sliderFadeDuration)); _expSliderFadeCoroutine = StartCoroutine(View.expSlider.SmoothValue(percent, _sliderFadeDuration));
} }
private void PlayerLevelUp(object sender, GameEventArgs e) private void PlayerLevelUp(object sender, GameEventArgs e)
@@ -235,7 +208,7 @@ namespace SepCore.UI
if (!(e is PlayerLevelUpEventArgs)) return; if (!(e is PlayerLevelUpEventArgs)) return;
_playerCurrentLevel++; _playerCurrentLevel++;
_expText.text = $"LV.{_playerCurrentLevel}"; View.expFormatText.Set(_playerCurrentLevel);
} }
private void PlayerCoinChange(object sender, GameEventArgs e) private void PlayerCoinChange(object sender, GameEventArgs e)
@@ -243,7 +216,7 @@ namespace SepCore.UI
if (!(e is PlayerCoinChangeEventArgs args)) return; if (!(e is PlayerCoinChangeEventArgs args)) return;
if (_currentCoin == args.CoinCount) return; if (_currentCoin == args.CoinCount) return;
_coinText.text = $"<sprite name=\"coin\" index=0> {args.CoinCount}"; View.coinFormatText.Set(args.CoinCount);
_currentCoin = args.CoinCount; _currentCoin = args.CoinCount;
} }
@@ -253,7 +226,7 @@ namespace SepCore.UI
if (_currentTimeLeft == args.LevelTimeLeft) return; if (_currentTimeLeft == args.LevelTimeLeft) return;
_currentTimeLeft = args.LevelTimeLeft; _currentTimeLeft = args.LevelTimeLeft;
_levelTimeLeftText.text = _currentTimeLeft.ToString(); View.countdownText.text = _currentTimeLeft.ToString();
} }
#endregion #endregion
@@ -0,0 +1,13 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class HudForm : UGuiForm
{
[SerializeField] private HudView _view = null;
public HudView View => _view;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f50fc6aab9e9b4846b0a80dd670c94b7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class HudView : MonoBehaviour
{
[SerializeField] public global::UnityEngine.UI.Slider hpSlider;
[SerializeField] public global::SepCore.UI.FormatTextUI hpFormatText;
[SerializeField] public global::UnityEngine.UI.Slider expSlider;
[SerializeField] public global::SepCore.UI.FormatTextUI expFormatText;
[SerializeField] public global::SepCore.UI.FormatTextUI coinFormatText;
[SerializeField] public global::SepCore.UI.FormatTextUI enemyCountFormatText;
[SerializeField] public global::SepCore.UI.FormatTextUI cpuTimeCostFormatText;
[SerializeField] public global::TMPro.TextMeshProUGUI countdownText;
[SerializeField] public global::UnityEngine.RectTransform inputPromptObject;
[SerializeField] public global::TMPro.TextMeshProUGUI inputPromptText;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 128e0c828a462a242a89114f9c8b9d32
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -2,28 +2,13 @@ using System;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using SepCore.AsyncTask; using SepCore.AsyncTask;
using SepCore.Event; using SepCore.Event;
using TMPro;
using UnityEngine; using UnityEngine;
using UnityGameFramework.Runtime; using UnityGameFramework.Runtime;
namespace SepCore.UI namespace SepCore.UI
{ {
public class ItemTooltipForm : UGuiForm public partial class ItemTooltipForm : UGuiForm
{ {
[SerializeField] private RectTransform _content;
[SerializeField] private IconArea _iconArea;
[SerializeField] private TMP_Text _itemTitle;
[SerializeField] private TMP_Text _itemTypeText;
[SerializeField] private TMP_Text _itemDescription;
[SerializeField] private CommonButton _recycleButton;
[SerializeField] private TMP_Text _itemPrice;
[SerializeField] private bool _autoResizeHeight = true; [SerializeField] private bool _autoResizeHeight = true;
[SerializeField] private float _fixedTopHeight = 150f; [SerializeField] private float _fixedTopHeight = 150f;
@@ -38,21 +23,24 @@ namespace SepCore.UI
private Vector3 _targetPos; private Vector3 _targetPos;
private bool _listenersBound;
public async UniTaskVoid RefreshUI(ItemTooltipContext context) public async UniTaskVoid RefreshUI(ItemTooltipContext context)
{ {
EnsureListeners();
_context = context; _context = context;
_targetPos = ConvertWorldToAnchored(_context.TargetPos); _targetPos = ConvertWorldToAnchored(_context.TargetPos);
Log.Info($"{_context.TargetPos}->{_targetPos}");
_content.anchoredPosition3D = _targetPos; View.contentRectTransform.anchoredPosition3D = _targetPos;
_itemTitle.text = _context.Title; View.titleText.text = _context.Title;
_itemTypeText.text = BuildTypeText(_context.ItemType); View.typeText.text = BuildTypeText(_context.ItemType);
_itemDescription.text = _context.Description; View.infoText.text = _context.Description;
_itemPrice.text = $"{_context.Price} <sprite name=\"coin\" index=0>"; View.textFormatText.Set(_context.Price);
_recycleButton.gameObject.SetActive(_context.ShowRecycleButton); View.recycleButton.gameObject.SetActive(_context.ShowRecycleButton);
if (!string.IsNullOrEmpty(_context.IconAssetName)) if (!string.IsNullOrEmpty(_context.IconAssetName))
{ {
@@ -60,7 +48,7 @@ namespace SepCore.UI
var sprite = await SpriteLoader.LoadSpriteByKeyAsync(iconAssetName); var sprite = await SpriteLoader.LoadSpriteByKeyAsync(iconAssetName);
if (_context != null && _context.IconAssetName == iconAssetName) if (_context != null && _context.IconAssetName == iconAssetName)
{ {
_iconArea.OnInit(sprite, context.Rarity); View.iconArea.OnInit(sprite, context.Rarity);
ResizeToFitContent(); ResizeToFitContent();
ApplyClampedTargetPos(); ApplyClampedTargetPos();
} }
@@ -74,7 +62,7 @@ namespace SepCore.UI
{ {
base.OnOpen(userData); base.OnOpen(userData);
if (!(userData is ItemTooltipContext context)) if (userData is not ItemTooltipContext context)
{ {
Log.Error("ItemTooltipForm context is invalid."); Log.Error("ItemTooltipForm context is invalid.");
return; return;
@@ -89,6 +77,29 @@ namespace SepCore.UI
base.OnClose(isShutdown, userData); base.OnClose(isShutdown, userData);
} }
public void OnRecycleButtonClick()
{
GameEntry.Event.Fire(this, ItemTooltipRecycleEventArgs.Create(_context.Index, _context.Price));
}
public void OnCancelButtonClick()
{
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create());
}
private void EnsureListeners()
{
if (_listenersBound)
{
return;
}
_listenersBound = true;
View.recycleButton.onClick.AddListener(OnRecycleButtonClick);
View.cancelButton.onClick.AddListener(OnCancelButtonClick);
}
private void ResizeToFitContent() private void ResizeToFitContent()
{ {
if (!_autoResizeHeight) if (!_autoResizeHeight)
@@ -96,32 +107,32 @@ namespace SepCore.UI
return; return;
} }
_itemDescription.ForceMeshUpdate(); View.infoText.ForceMeshUpdate();
var descriptionSize = _itemDescription.rectTransform.sizeDelta; var descriptionSize = View.infoText.rectTransform.sizeDelta;
descriptionSize.y = _itemDescription.preferredHeight; descriptionSize.y = View.infoText.preferredHeight;
_itemDescription.rectTransform.sizeDelta = descriptionSize; View.infoText.rectTransform.sizeDelta = descriptionSize;
float descriptionHeight = Mathf.Max(0f, _itemDescription.preferredHeight); float descriptionHeight = Mathf.Max(0f, View.infoText.preferredHeight);
float targetHeight = _fixedTopHeight + descriptionHeight + _fixedBottomHeight; float targetHeight = _fixedTopHeight + descriptionHeight + _fixedBottomHeight;
Vector2 size = new Vector2(_fixedWidth, targetHeight); Vector2 size = new Vector2(_fixedWidth, targetHeight);
_content.sizeDelta = size; View.contentRectTransform.sizeDelta = size;
} }
private void ApplyClampedTargetPos() private void ApplyClampedTargetPos()
{ {
RectTransform parent = _content.parent as RectTransform; RectTransform parent = View.contentRectTransform.parent as RectTransform;
if (parent == null) if (parent == null)
{ {
return; return;
} }
Vector2 size = _content.sizeDelta; Vector2 size = View.contentRectTransform.sizeDelta;
if (size.x <= 0f || size.y <= 0f) if (size.x <= 0f || size.y <= 0f)
{ {
size = _content.rect.size; size = View.contentRectTransform.rect.size;
} }
Vector2 pivot = _content.pivot; Vector2 pivot = View.contentRectTransform.pivot;
float halfWidth = parent.rect.width * 0.5f; float halfWidth = parent.rect.width * 0.5f;
float halfHeight = parent.rect.height * 0.5f; float halfHeight = parent.rect.height * 0.5f;
@@ -133,18 +144,18 @@ namespace SepCore.UI
float clampedX = minX <= maxX ? Mathf.Clamp(_targetPos.x, minX, maxX) : 0f; float clampedX = minX <= maxX ? Mathf.Clamp(_targetPos.x, minX, maxX) : 0f;
float clampedY = minY <= maxY ? Mathf.Clamp(_targetPos.y, minY, maxY) : 0f; float clampedY = minY <= maxY ? Mathf.Clamp(_targetPos.y, minY, maxY) : 0f;
_content.anchoredPosition3D = new Vector3(clampedX, clampedY, _targetPos.z); View.contentRectTransform.anchoredPosition3D = new Vector3(clampedX, clampedY, _targetPos.z);
} }
private Vector3 ConvertWorldToAnchored(Vector3 worldPos) private Vector3 ConvertWorldToAnchored(Vector3 worldPos)
{ {
RectTransform parent = _content.parent as RectTransform; RectTransform parent = View.contentRectTransform.parent as RectTransform;
if (parent == null) if (parent == null)
{ {
return worldPos; return worldPos;
} }
Canvas canvas = _content.GetComponentInParent<Canvas>(); Canvas canvas = View.contentRectTransform.GetComponentInParent<Canvas>();
Canvas rootCanvas = canvas != null ? canvas.rootCanvas : null; Canvas rootCanvas = canvas != null ? canvas.rootCanvas : null;
Camera uiCamera = null; Camera uiCamera = null;
if (rootCanvas != null && rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay) if (rootCanvas != null && rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay)
@@ -159,20 +170,10 @@ namespace SepCore.UI
return worldPos; return worldPos;
} }
float z = _content.anchoredPosition3D.z; float z = View.contentRectTransform.anchoredPosition3D.z;
return new Vector3(localPoint.x, localPoint.y, z); return new Vector3(localPoint.x, localPoint.y, z);
} }
public void OnRecycleButtonClick()
{
GameEntry.Event.Fire(this, ItemTooltipRecycleEventArgs.Create(_context.Index, _context.Price));
}
public void OnCancelButtonClick()
{
GameEntry.Event.Fire(this, ItemTooltipHideEventArgs.Create());
}
private string BuildTypeText(ItemType type) private string BuildTypeText(ItemType type)
{ {
return type switch return type switch
@@ -0,0 +1,13 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class ItemTooltipForm : UGuiForm
{
[SerializeField] private ItemTooltipView _view = null;
public ItemTooltipView View => _view;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7489a7d3442947647bee8612880a3f83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,18 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class ItemTooltipView : MonoBehaviour
{
[SerializeField] public global::UnityEngine.RectTransform contentRectTransform;
[SerializeField] public global::SepCore.UI.IconArea iconArea;
[SerializeField] public global::TMPro.TextMeshProUGUI titleText;
[SerializeField] public global::TMPro.TextMeshProUGUI typeText;
[SerializeField] public global::TMPro.TextMeshProUGUI infoText;
[SerializeField] public global::SepCore.UI.CommonButton recycleButton;
[SerializeField] public global::SepCore.UI.FormatTextUI textFormatText;
[SerializeField] public global::SepCore.UI.CommonButton cancelButton;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4d9524b70efb9c840a84baed8b0c12d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,108 @@
using System.Collections.Generic;
using SepCore.Event;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
public partial class LevelUpForm : UGuiForm
{
private readonly List<LevelUpRewardItem> _rewardItems = new List<LevelUpRewardItem>();
private LevelUpContext _context;
private bool _listenersBound;
public void RefreshUI(LevelUpContext context)
{
EnsureButtonListeners();
_context = context;
if (View.levelUpRewardTemplate.gameObject.activeSelf)
{
View.levelUpRewardTemplate.gameObject.SetActive(false);
}
int count = _context.Props?.Count ?? 0;
EnsureRewardItemCount(count);
for (int i = 0; i < _rewardItems.Count; i++)
{
LevelUpRewardItem item = _rewardItems[i];
if (i < count)
{
item.Init(_context.Props[i]);
item.gameObject.SetActive(true);
}
else
{
item.gameObject.SetActive(false);
}
}
// 刷新 -20 <sprite name="coin" index=0>
View.refreshCostFormatText.Set(context.RefreshPrice);
}
#region Lifecycle
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is not LevelUpContext context)
{
Log.Error("LevelUpForm requires LevelUpContext as userData.");
return;
}
RefreshUI(context);
}
protected override void OnClose(bool isShutdown, object userData)
{
_context = null;
base.OnClose(isShutdown, userData);
}
#endregion
private void EnsureButtonListeners()
{
if (_listenersBound)
{
return;
}
_listenersBound = true;
View.refreshButton.onClick.AddListener(OnRefreshButtonClick);
}
private void EnsureRewardItemCount(int count)
{
while (_rewardItems.Count < count)
{
int index = _rewardItems.Count;
LevelUpRewardItem item = Instantiate(View.levelUpRewardTemplate, View.rewardAreaRoot);
CommonButton button = item.GetComponentInChildren<CommonButton>();
if (button != null)
{
button.onClick.AddListener(() => OnSelectButtonClick(index));
}
_rewardItems.Add(item);
}
}
public void OnSelectButtonClick(int index)
{
GameEntry.Event.Fire(this, LevelUpPropSelectedEventArgs.Create(index));
}
public void OnRefreshButtonClick()
{
GameEntry.Event.Fire(this, LevelUpRefreshEventArgs.Create(_context.RefreshPrice));
}
}
}
@@ -0,0 +1,13 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class LevelUpForm : UGuiForm
{
[SerializeField] private LevelUpView _view = null;
public LevelUpView View => _view;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3172a8000d5463f45b2f4c5f5a19433d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 32bf4a12bd0ac2847b19bbb76b7c3dd5 guid: 0f0b958b02844f940982990f3922c912
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
@@ -0,0 +1,14 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class LevelUpView : MonoBehaviour
{
[SerializeField] public global::UnityEngine.RectTransform rewardAreaRoot;
[SerializeField] public global::SepCore.UI.LevelUpRewardItem levelUpRewardTemplate;
[SerializeField] public global::SepCore.UI.CommonButton refreshButton;
[SerializeField] public global::SepCore.UI.FormatTextUI refreshCostFormatText;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39b4ea16f6b8d6a47b6ea7078982a7d0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,69 +0,0 @@
using SepCore.Event;
using TMPro;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
public class LevelUpForm : UGuiForm
{
[SerializeField] private LevelUpRewardItem[] _propItems;
[SerializeField] private TMP_Text _refreshButtonText;
private LevelUpContext _context;
public void RefreshUI(LevelUpContext context)
{
_context = context;
foreach (var propItem in _propItems)
{
propItem.gameObject.SetActive(false);
}
int count = Mathf.Min(_propItems.Length, _context.Props.Count);
for (int i = 0; i < count; i++)
{
_propItems[i].gameObject.SetActive(true);
_propItems[i].Init(_context.Props[i]);
}
//刷新 -20 <sprite name="coin" index=0>
_refreshButtonText.text = $"刷新 -{context.RefreshPrice} <sprite name=\"coin\" index=0>";
}
#region FSM
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (userData is not LevelUpContext context)
{
Log.Error("LevelUpForm requires LevelUpContext as userData.");
return;
}
RefreshUI(context);
}
protected override void OnClose(bool isShutdown, object userData)
{
_context = null;
base.OnClose(isShutdown, userData);
}
#endregion
public void OnSelectButtonClick(int index)
{
GameEntry.Event.Fire(this, LevelUpPropSelectedEventArgs.Create(index));
}
public void OnRefreshButtonClick()
{
GameEntry.Event.Fire(this, LevelUpRefreshEventArgs.Create(_context.RefreshPrice));
}
}
}
@@ -1,226 +0,0 @@
using System;
using System.Collections.Generic;
using GameFramework.ObjectPool;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace SepCore.UI
{
public enum DisplayListAreaType : byte
{
None = 0,
Prop = 1,
Weapon = 2
}
public class DisplayListArea : MonoBehaviour
{
[SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _countText;
[SerializeField] private DisplayItem _displayItemTemplate;
[SerializeField] private Transform _displayItemRoot;
[SerializeField] private Vector2 _startPosition = Vector2.zero;
[SerializeField] private float _itemSize = 150f;
[SerializeField] private float _itemSpacing = 10f;
[SerializeField] private int _fixedColumnCount = 0;
[SerializeField] private int _instancePoolCapacity = 32;
private DisplayListAreaContext _context;
private IObjectPool<DisplayItemObject> _displayItemObjectPool;
private const string DisplayItemPoolName = "DisplayItem";
private readonly List<DisplayItem> _activeItems = new List<DisplayItem>();
public void OnInit(DisplayListAreaContext context)
{
EnsurePool();
_context = context;
_titleText.text = context.Title;
UpdateCountText(context.CurrentCount, context.MaxCount);
int targetCount = Mathf.Min(context.CurrentCount, context.ItemContexts.Length);
EnsureItemCount(targetCount);
for (int i = 0; i < targetCount; i++)
{
_activeItems[i].OnInit(context.ItemContexts[i], i).Forget();
}
LayoutItems();
}
public void OnReset()
{
_context = null;
for (int i = _activeItems.Count - 1; i >= 0; i--)
{
HideItem(_activeItems[i]);
}
}
public void OnDestroy()
{
_displayItemObjectPool?.ReleaseAllUnused();
}
public DisplayItem AddItem(DisplayItemContext itemContext)
{
EnsurePool();
DisplayItem item = CreateItem();
int index = _activeItems.Count;
_activeItems.Add(item);
item.OnInit(itemContext, index).Forget();
item.SetIndex(index);
int columnCount = _fixedColumnCount > 0 ? _fixedColumnCount : CalculateColumnCount(GetRootWidth());
LayoutItem(item, index, columnCount);
int currentCount = _activeItems.Count;
_context.CurrentCount = currentCount;
UpdateCountText(currentCount, _context.MaxCount);
return item;
}
public bool RemoveItemAt(int index)
{
if (index < 0 || index >= _activeItems.Count)
{
return false;
}
HideItem(_activeItems[index]);
LayoutItems();
int currentCount = _activeItems.Count;
_context.CurrentCount = currentCount;
UpdateCountText(currentCount, _context.MaxCount);
return true;
}
private void EnsurePool()
{
if (_displayItemObjectPool != null) return;
GridLayoutGroup gridLayout = _displayItemRoot.GetComponent<GridLayoutGroup>();
if (gridLayout != null)
{
gridLayout.enabled = false;
}
if (GameEntry.ObjectPool.HasObjectPool<DisplayItemObject>(DisplayItemPoolName))
{
_displayItemObjectPool = GameEntry.ObjectPool.GetObjectPool<DisplayItemObject>(DisplayItemPoolName);
return;
}
_displayItemObjectPool =
GameEntry.ObjectPool.CreateSingleSpawnObjectPool<DisplayItemObject>(DisplayItemPoolName,
_instancePoolCapacity);
}
private void EnsureItemCount(int count)
{
for (int i = _activeItems.Count; i < count; i++)
{
_activeItems.Add(CreateItem());
}
for (int i = _activeItems.Count - 1; i >= count; i--)
{
HideItem(_activeItems[i]);
}
}
private DisplayItem CreateItem()
{
DisplayItem item;
DisplayItemObject itemObject = _displayItemObjectPool.Spawn();
if (itemObject != null)
{
item = (DisplayItem)itemObject.Target;
}
else
{
item = Instantiate(_displayItemTemplate);
_displayItemObjectPool.Register(DisplayItemObject.Create(item), true);
}
item.transform.SetParent(_displayItemRoot, false);
item.gameObject.SetActive(true);
return item;
}
private void HideItem(DisplayItem item)
{
item.OnReset();
_activeItems.Remove(item);
item.gameObject.SetActive(false);
_displayItemObjectPool.Unspawn(item);
}
private void LayoutItems()
{
int columnCount = _fixedColumnCount > 0 ? _fixedColumnCount : CalculateColumnCount(GetRootWidth());
for (int i = 0; i < _activeItems.Count; i++)
{
DisplayItem item = _activeItems[i];
item.SetIndex(i);
LayoutItem(item, i, columnCount);
}
}
private void LayoutItem(DisplayItem item, int index, int columnCount)
{
RectTransform itemRect = item.GetComponent<RectTransform>();
float step = _itemSize + _itemSpacing;
int row = index / columnCount;
int col = index % columnCount;
itemRect.anchorMin = new Vector2(0f, 1f);
itemRect.anchorMax = new Vector2(0f, 1f);
itemRect.pivot = new Vector2(0f, 1f);
itemRect.sizeDelta = new Vector2(_itemSize, _itemSize);
itemRect.anchoredPosition = _startPosition + new Vector2(col * step, -row * step);
}
private float GetRootWidth()
{
RectTransform rootRect = (RectTransform)_displayItemRoot;
return rootRect.rect.width;
}
private int CalculateColumnCount(float rootWidth)
{
if (rootWidth <= 0f) return 1;
float step = _itemSize + _itemSpacing;
int columns = Mathf.FloorToInt((rootWidth + _itemSpacing) / step);
return Mathf.Max(1, columns);
}
private void UpdateCountText(int currentCount, int maxCount)
{
_countText.text = maxCount == -1 ? $"({currentCount})" : $"({currentCount}/{maxCount})";
}
}
}
@@ -1,14 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SepCore.UI
{
public class DisplayListAreaContext : UIContext
{
public string Title;
public int CurrentCount;
public int MaxCount = -1;
public DisplayItemContext[] ItemContexts;
}
}
@@ -1,27 +0,0 @@
using GameFramework;
using GameFramework.ObjectPool;
using UnityEngine;
namespace SepCore.UI
{
public class DisplayItemObject : ObjectBase
{
public static DisplayItemObject Create(object target)
{
DisplayItemObject displayItemObject = ReferencePool.Acquire<DisplayItemObject>();
displayItemObject.Initialize(target);
return displayItemObject;
}
protected override void Release(bool isShutdown)
{
DisplayItem item = (DisplayItem)Target;
if (item == null)
{
return;
}
Object.Destroy(item.gameObject);
}
}
}
@@ -8,8 +8,8 @@ namespace SepCore.UI
public int RefreshPrice; public int RefreshPrice;
public int PlayerCoin; public int PlayerCoin;
public List<GoodsItemContext> GoodsItems; public List<GoodsItemContext> GoodsItems;
public DisplayListAreaContext PropListContext; public DisplayListContext PropListContext;
public DisplayListAreaContext WeaponListContext; public DisplayListContext WeaponListContext;
// 控制字段 // 控制字段
public bool NeedRefreshGoodsItems; public bool NeedRefreshGoodsItems;
@@ -7,6 +7,13 @@ using UnityGameFramework.Runtime;
namespace SepCore.UI namespace SepCore.UI
{ {
public enum DisplayListAreaType : byte
{
None = 0,
Prop = 1,
Weapon = 2
}
public partial class ShopController public partial class ShopController
{ {
private async UniTask<ShopContext> BuildContext(ShopRawData rawData) private async UniTask<ShopContext> BuildContext(ShopRawData rawData)
@@ -30,8 +37,8 @@ namespace SepCore.UI
{ {
GoodsItems = goodsItems, GoodsItems = goodsItems,
PropListContext = PropListContext =
BuildDisplayListAreaContext(DisplayListAreaType.Prop, rawData.PropItems, rawData.PropMaxCount), BuildDisplayListContext(DisplayListAreaType.Prop, rawData.PropItems, rawData.PropMaxCount),
WeaponListContext = BuildDisplayListAreaContext(DisplayListAreaType.Weapon, rawData.WeaponItems, WeaponListContext = BuildDisplayListContext(DisplayListAreaType.Weapon, rawData.WeaponItems,
rawData.WeaponMaxCount), rawData.WeaponMaxCount),
NeedRefreshGoodsItems = true, NeedRefreshGoodsItems = true,
NeedRefreshPlayerCoin = true, NeedRefreshPlayerCoin = true,
@@ -41,7 +48,7 @@ namespace SepCore.UI
}; };
} }
private static DisplayListAreaContext BuildDisplayListAreaContext(DisplayListAreaType listType, private static DisplayListContext BuildDisplayListContext(DisplayListAreaType listType,
IReadOnlyList<object> items, int maxCount) IReadOnlyList<object> items, int maxCount)
{ {
DisplayItemContext[] itemContexts = new DisplayItemContext[items.Count]; DisplayItemContext[] itemContexts = new DisplayItemContext[items.Count];
@@ -66,25 +73,14 @@ namespace SepCore.UI
break; break;
} }
return new DisplayListAreaContext return new DisplayListContext
{ {
Title = GetDisplayListTitle(listType),
CurrentCount = itemContexts.Length, CurrentCount = itemContexts.Length,
MaxCount = maxCount, MaxCount = maxCount,
ItemContexts = itemContexts ItemContexts = itemContexts
}; };
} }
private static string GetDisplayListTitle(DisplayListAreaType listType)
{
return listType switch
{
DisplayListAreaType.Weapon => "武器",
DisplayListAreaType.Prop => "道具",
_ => string.Empty
};
}
private static DisplayItemContext BuildPropItem(PropItem propItem) private static DisplayItemContext BuildPropItem(PropItem propItem)
{ {
return new DisplayItemContext return new DisplayItemContext
@@ -105,7 +101,7 @@ namespace SepCore.UI
}; };
} }
private static void AppendDisplayItemContext(DisplayListAreaContext listContext, DisplayItemContext newItem) private static void AppendDisplayItemContext(DisplayListContext listContext, DisplayItemContext newItem)
{ {
int oldCount = listContext.ItemContexts.Length; int oldCount = listContext.ItemContexts.Length;
DisplayItemContext[] newContexts = new DisplayItemContext[oldCount + 1]; DisplayItemContext[] newContexts = new DisplayItemContext[oldCount + 1];
@@ -1,115 +1,56 @@
using System.Collections.Generic; using System.Collections.Generic;
using SepCore.Event; using SepCore.Event;
using TMPro;
using UnityEngine;
using UnityGameFramework.Runtime; using UnityGameFramework.Runtime;
namespace SepCore.UI namespace SepCore.UI
{ {
public class ShopForm : UGuiForm public partial class ShopForm : UGuiForm
{ {
#region Property private readonly List<ShopGoodsItem> _goodsItems = new List<ShopGoodsItem>();
[SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _continueButtonText;
[SerializeField] private TMP_Text _refreshPriceText;
[SerializeField] private TMP_Text _playerCoinText;
[SerializeField] private ShopGoodsItem[] _goodsItems;
[SerializeField] private DisplayListArea _propListArea;
[SerializeField] private DisplayListArea _weaponListArea;
private ShopContext _context; private ShopContext _context;
#endregion private bool _listenersBound;
public void RefreshUI(ShopContext context) public void RefreshUI(ShopContext context)
{ {
EnsureButtonListeners();
_context = context; _context = context;
// 首次打开或需要全量刷新时
if (context.NeedRefreshGoodsItems) if (context.NeedRefreshGoodsItems)
{ {
_titleText.text = $"商店 (Lv.{context.CurrentLevel})"; View.titleFormatText.Set(context.CurrentLevel);
_continueButtonText.text = $"继续 (Lv.{context.CurrentLevel + 1})"; View.continueButtonFormatText.Set(context.CurrentLevel + 1);
RefreshGoodsItems(context.GoodsItems); RefreshGoodsItems(context.GoodsItems);
context.NeedRefreshGoodsItems = false; context.NeedRefreshGoodsItems = false;
} }
if (context.NeedRefreshPrice) if (context.NeedRefreshPrice)
{ {
RefreshRefreshPrice(context.RefreshPrice); View.refreshButtonFormatText.Set(context.RefreshPrice);
context.NeedRefreshPrice = false; context.NeedRefreshPrice = false;
} }
if (context.NeedRefreshPlayerCoin) if (context.NeedRefreshPlayerCoin)
{ {
_playerCoinText.text = $"<sprite name=\"coin\"> {context.PlayerCoin}"; View.playerCoinFormatText.Set(context.PlayerCoin);
context.NeedRefreshPlayerCoin = false; context.NeedRefreshPlayerCoin = false;
} }
if (context.NeedRefreshPropList) if (context.NeedRefreshPropList)
{ {
_propListArea.OnInit(context.PropListContext); View.propList.OnInit(context.PropListContext);
context.NeedRefreshPropList = false; context.NeedRefreshPropList = false;
} }
if (context.NeedRefreshWeaponList) if (context.NeedRefreshWeaponList)
{ {
_weaponListArea.OnInit(context.WeaponListContext); View.weaponList.OnInit(context.WeaponListContext);
context.NeedRefreshWeaponList = false; context.NeedRefreshWeaponList = false;
} }
} }
private void RefreshGoodsItems(List<GoodsItemContext> goodsItems)
{
foreach (var item in _goodsItems)
{
item.gameObject.SetActive(false);
}
int count = Mathf.Min(_goodsItems.Length, goodsItems.Count);
for (int i = 0; i < count; i++)
{
if (goodsItems[i] == null) continue;
_goodsItems[i].Init(goodsItems[i]);
_goodsItems[i].gameObject.SetActive(true);
}
}
private void RefreshRefreshPrice(int refreshPrice)
{
_refreshPriceText.text = $"刷新 -{refreshPrice} <sprite name=\"coin\">";
}
#region ButtonClick
public void OnContinueButtonClick()
{
GameEntry.Event.Fire(this, ShopContinueEventArgs.Create());
}
public void OnPurchaseButtonClick(int index)
{
GameEntry.Event.Fire(this, ShopPurchaseEventArgs.Create(index));
}
public void OnRefreshButtonClick()
{
GameEntry.Event.Fire(this, ShopRefreshEventArgs.Create(_context.RefreshPrice));
}
#endregion
#region FSM
protected override void OnOpen(object userData) protected override void OnOpen(object userData)
{ {
base.OnOpen(userData); base.OnOpen(userData);
@@ -127,12 +68,67 @@ namespace SepCore.UI
{ {
_context = null; _context = null;
_propListArea.OnReset(); for (int i = 0; i < _goodsItems.Count; i++)
_weaponListArea.OnReset(); {
_goodsItems[i].OnReset();
}
View.propList.OnReset();
View.weaponList.OnReset();
base.OnClose(isShutdown, userData); base.OnClose(isShutdown, userData);
} }
#endregion private void EnsureButtonListeners()
{
if (_listenersBound)
{
return;
}
_listenersBound = true;
View.continueButton.onClick.AddListener(OnContinueButtonClick);
View.refreshButton.onClick.AddListener(OnRefreshButtonClick);
}
private void RefreshGoodsItems(List<GoodsItemContext> goodsItems)
{
EnsureGoodsItemCount(goodsItems.Count);
for (int i = 0; i < _goodsItems.Count; i++)
{
ShopGoodsItem item = _goodsItems[i];
if (i < goodsItems.Count && goodsItems[i] != null)
{
item.Init(goodsItems[i], i);
item.gameObject.SetActive(true);
}
else
{
item.OnReset();
item.gameObject.SetActive(false);
}
}
}
private void EnsureGoodsItemCount(int count)
{
while (_goodsItems.Count < count)
{
ShopGoodsItem item = Instantiate(View.goodsItemTemplate, View.GoodsItemRoot);
_goodsItems.Add(item);
}
}
public void OnContinueButtonClick()
{
GameEntry.Event.Fire(this, ShopContinueEventArgs.Create());
}
public void OnRefreshButtonClick()
{
GameEntry.Event.Fire(this, ShopRefreshEventArgs.Create(_context.RefreshPrice));
}
} }
} }
@@ -0,0 +1,13 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class ShopForm : UGuiForm
{
[SerializeField] private ShopView _view = null;
public ShopView View => _view;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b261ad08be35724a83c21227db57e6b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,26 +1,32 @@
using System; using System;
using SepCore.Event;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.UI;
namespace SepCore.UI namespace SepCore.UI
{ {
public class ShopGoodsItem : MonoBehaviour public class ShopGoodsItem : MonoBehaviour
{ {
[SerializeField] private IconArea _iconArea; [SerializeField] private IconArea _iconArea;
[SerializeField] private TMP_Text _titleText; [SerializeField] private TMP_Text _titleText;
[SerializeField] private TMP_Text _typeText; [SerializeField] private TMP_Text _typeText;
[SerializeField] private TMP_Text _descriptionText; [SerializeField] private TMP_Text _descriptionText;
[SerializeField] private TMP_Text _costText; [SerializeField] private TMP_Text _costText;
#region Init private int _index = -1;
public void Init(GoodsItemContext data) private bool _listenersBound;
public void Init(GoodsItemContext data, int index)
{ {
EnsureListeners();
_index = index;
_iconArea.OnInit(data.Icon, data.Rarity); _iconArea.OnInit(data.Icon, data.Rarity);
_titleText.text = data.Name; _titleText.text = data.Name;
_typeText.text = data.ItemType switch _typeText.text = data.ItemType switch
@@ -34,6 +40,32 @@ namespace SepCore.UI
_costText.text = $"{data.Price} <sprite name=\"coin\" index=0>"; _costText.text = $"{data.Price} <sprite name=\"coin\" index=0>";
} }
#endregion public void OnReset()
{
_index = -1;
}
private void EnsureListeners()
{
if (_listenersBound)
{
return;
}
_listenersBound = true;
CommonButton button = GetComponentInChildren<CommonButton>(true);
button.onClick.AddListener(OnPurchaseClick);
}
private void OnPurchaseClick()
{
if (_index < 0)
{
return;
}
GameEntry.Event.Fire(this, ShopPurchaseEventArgs.Create(_index));
}
} }
} }
@@ -0,0 +1,20 @@
// <auto-generated />
using UnityEngine;
namespace SepCore.UI
{
[DisallowMultipleComponent]
public partial class ShopView : MonoBehaviour
{
[SerializeField] public global::SepCore.UI.FormatTextUI titleFormatText;
[SerializeField] public global::SepCore.UI.FormatTextUI playerCoinFormatText;
[SerializeField] public global::SepCore.UI.CommonButton refreshButton;
[SerializeField] public global::SepCore.UI.FormatTextUI refreshButtonFormatText;
[SerializeField] public global::UnityEngine.RectTransform GoodsItemRoot;
[SerializeField] public global::SepCore.UI.ShopGoodsItem goodsItemTemplate;
[SerializeField] public global::SepCore.UI.CommonButton continueButton;
[SerializeField] public global::SepCore.UI.FormatTextUI continueButtonFormatText;
[SerializeField] public global::SepCore.UI.DisplayListForm weaponList;
[SerializeField] public global::SepCore.UI.DisplayListForm propList;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10a546b2f753668479061813a7f5781f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -20,6 +20,7 @@ namespace SepCore.CustomComponent
{ {
"tbenemyconfig", "tbenemyconfig",
"tbentityconfig", "tbentityconfig",
"tbformattext",
"tbglobalconfig", "tbglobalconfig",
"tbgoodsconfig", "tbgoodsconfig",
"tblevelconfig", "tblevelconfig",
@@ -57,6 +58,11 @@ namespace SepCore.CustomComponent
StringAccessor(tables => key => tables.TbEntityConfig.GetOrDefault(key), StringAccessor(tables => key => tables.TbEntityConfig.GetOrDefault(key),
tables => tables.TbEntityConfig.DataList) tables => tables.TbEntityConfig.DataList)
}, },
{
typeof(FormatText),
StringAccessor(tables => key => tables.TbFormatText.GetOrDefault(key),
tables => tables.TbFormatText.DataList)
},
{ {
typeof(GoodsConfig), typeof(GoodsConfig),
Accessor(tables => id => tables.TbGoodsConfig.GetOrDefault(id), Accessor(tables => id => tables.TbGoodsConfig.GetOrDefault(id),
@@ -165,7 +171,7 @@ namespace SepCore.CustomComponent
public bool IsReady => Tables != null; public bool IsReady => Tables != null;
public TbGlobalConfig Global => Tables.TbGlobalConfig; public TbGlobalConfig Global => Tables.TbGlobalConfig;
/// <summary> /// <summary>
/// 按 id 获取数据行,未找到时返回 null。 /// 按 id 获取数据行,未找到时返回 null。
/// </summary> /// </summary>
@@ -191,6 +197,7 @@ namespace SepCore.CustomComponent
{ {
return (T)accessor.StringRowGetter(Tables, id.ToString()); return (T)accessor.StringRowGetter(Tables, id.ToString());
} }
throw new NotSupportedException("Table for type '" + typeof(T).FullName + "' does not use an int key."); throw new NotSupportedException("Table for type '" + typeof(T).FullName + "' does not use an int key.");
} }
@@ -222,7 +229,9 @@ namespace SepCore.CustomComponent
{ {
return (T)accessor.RowGetter(Tables, parsedId); return (T)accessor.RowGetter(Tables, parsedId);
} }
throw new NotSupportedException("Table for type '" + typeof(T).FullName + "' does not use a string key.");
throw new NotSupportedException(
"Table for type '" + typeof(T).FullName + "' does not use a string key.");
} }
return (T)accessor.StringRowGetter(Tables, key); return (T)accessor.StringRowGetter(Tables, key);
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 7af0b9398035e254cb6de37a6c301552 guid: f228612923ff51343a4dab06ce4c1f92
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 166c0ae58c1d0b34ababe6d3a3791efa guid: 8e4010de30b33144fa20400058edfeba
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6b12df2039d69e14aa018b259f3789cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 35c8961f073eae8479506bdec8b745f8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: dd09af1a9a441da409e57f235fbff385
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+340 -16
View File
@@ -10,6 +10,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 1898912521751469060} - component: {fileID: 1898912521751469060}
- component: {fileID: 5299361850566254458} - component: {fileID: 5299361850566254458}
- component: {fileID: 2683555179817567623}
m_Layer: 5 m_Layer: 5
m_Name: Slider m_Name: Slider
m_TagString: Untagged m_TagString: Untagged
@@ -89,6 +90,25 @@ MonoBehaviour:
m_OnValueChanged: m_OnValueChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
--- !u!114 &2683555179817567623
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 354765269731237081}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 1898912521751469060}
generateReference: 0
variableName: sliderRectTransform
- component: {fileID: 5299361850566254458}
generateReference: 1
variableName: hpSlider
--- !u!1 &1093731290841678102 --- !u!1 &1093731290841678102
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -177,6 +197,7 @@ GameObject:
- component: {fileID: 844544797351374585} - component: {fileID: 844544797351374585}
- component: {fileID: 8628784289326000741} - component: {fileID: 8628784289326000741}
- component: {fileID: 4622934279017998176} - component: {fileID: 4622934279017998176}
- component: {fileID: 6147153731094542669}
m_Layer: 5 m_Layer: 5
m_Name: InputPrompt m_Name: InputPrompt
m_TagString: Untagged m_TagString: Untagged
@@ -302,6 +323,28 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &6147153731094542669
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1181223948078793352}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 844544797351374585}
generateReference: 1
variableName: inputPromptObject
- component: {fileID: 8628784289326000741}
generateReference: 0
variableName: inputPromptCanvasRenderer
- component: {fileID: 4622934279017998176}
generateReference: 1
variableName: inputPromptText
--- !u!1 &1254538346940764031 --- !u!1 &1254538346940764031
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -723,6 +766,8 @@ GameObject:
- component: {fileID: 2321401882073682150} - component: {fileID: 2321401882073682150}
- component: {fileID: 1782615630760369603} - component: {fileID: 1782615630760369603}
- component: {fileID: 2927128461236740550} - component: {fileID: 2927128461236740550}
- component: {fileID: 1338032805297419914}
- component: {fileID: 4085884790449951551}
m_Layer: 5 m_Layer: 5
m_Name: Text (TMP) m_Name: Text (TMP)
m_TagString: Untagged m_TagString: Untagged
@@ -847,6 +892,44 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &1338032805297419914
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5257437757145065837}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2efdcd06cdaa830448f76b22ea7c98fb, type: 3}
m_Name:
m_EditorClassIdentifier:
key: HUDCoinText
--- !u!114 &4085884790449951551
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5257437757145065837}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 2321401882073682150}
generateReference: 0
variableName: textTMPRectTransform
- component: {fileID: 1782615630760369603}
generateReference: 0
variableName: textTMPCanvasRenderer
- component: {fileID: 2927128461236740550}
generateReference: 0
variableName: textTMPTextMeshProUGUI
- component: {fileID: 1338032805297419914}
generateReference: 1
variableName: coinFormatText
--- !u!1 &5631092228615999952 --- !u!1 &5631092228615999952
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -857,6 +940,7 @@ GameObject:
m_Component: m_Component:
- component: {fileID: 8236818010774652375} - component: {fileID: 8236818010774652375}
- component: {fileID: 8665470951107162402} - component: {fileID: 8665470951107162402}
- component: {fileID: 3112243653259427451}
m_Layer: 5 m_Layer: 5
m_Name: Slider m_Name: Slider
m_TagString: Untagged m_TagString: Untagged
@@ -936,6 +1020,25 @@ MonoBehaviour:
m_OnValueChanged: m_OnValueChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
--- !u!114 &3112243653259427451
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5631092228615999952}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 8236818010774652375}
generateReference: 0
variableName: sliderRectTransform
- component: {fileID: 8665470951107162402}
generateReference: 1
variableName: expSlider
--- !u!1 &5770324452358855434 --- !u!1 &5770324452358855434
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -945,7 +1048,9 @@ GameObject:
serializedVersion: 6 serializedVersion: 6
m_Component: m_Component:
- component: {fileID: 5845023051097607336} - component: {fileID: 5845023051097607336}
- component: {fileID: 6441412682266920784} - component: {fileID: 1400725265441350809}
- component: {fileID: 5287927180934711754}
- component: {fileID: 8964044174534830133}
m_Layer: 5 m_Layer: 5
m_Name: HudForm m_Name: HudForm
m_TagString: Untagged m_TagString: Untagged
@@ -979,7 +1084,7 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &6441412682266920784 --- !u!114 &1400725265441350809
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
@@ -988,21 +1093,57 @@ MonoBehaviour:
m_GameObject: {fileID: 5770324452358855434} m_GameObject: {fileID: 5770324452358855434}
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bd4c4d6e8d4b0f54c830e2cfef46848e, type: 3} m_Script: {fileID: 11500000, guid: 335062b0d81ae40f49c923ef4bf19dd7, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
serializationItems:
- {fileID: 2683555179817567623}
- {fileID: 5839081052582000735}
- {fileID: 3112243653259427451}
- {fileID: 7322939721948672541}
- {fileID: 4085884790449951551}
- {fileID: 7818830623860974121}
- {fileID: 3804240423293578540}
- {fileID: 5196414089076549728}
- {fileID: 6147153731094542669}
nestedFormReferences: []
--- !u!114 &5287927180934711754
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5770324452358855434}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f50fc6aab9e9b4846b0a80dd670c94b7, type: 3}
m_Name:
m_EditorClassIdentifier:
_view: {fileID: 8964044174534830133}
_sliderFadeDuration: 0.5 _sliderFadeDuration: 0.5
_hpSlider: {fileID: 5299361850566254458}
_hpText: {fileID: 239521969410047457}
_expSlider: {fileID: 8665470951107162402}
_expText: {fileID: 1751630811530388523}
_coinText: {fileID: 2927128461236740550}
_levelTimeLeftText: {fileID: 4547091306916251724}
_enemyCountText: {fileID: 1716982582738894949}
_movePromptRoot: {fileID: 1181223948078793352}
_movePromptText: {fileID: 4622934279017998176}
_cpuTimeCostText: {fileID: 3568634826224029446}
_performanceStatsRefreshInterval: 0.2 _performanceStatsRefreshInterval: 0.2
--- !u!114 &8964044174534830133
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5770324452358855434}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 128e0c828a462a242a89114f9c8b9d32, type: 3}
m_Name:
m_EditorClassIdentifier:
hpSlider: {fileID: 5299361850566254458}
hpFormatText: {fileID: 3511617315799540544}
expSlider: {fileID: 8665470951107162402}
expFormatText: {fileID: 2782782041585949375}
coinFormatText: {fileID: 1338032805297419914}
enemyCountFormatText: {fileID: 40991353312457281}
cpuTimeCostFormatText: {fileID: 1437112477034048177}
countdownText: {fileID: 4547091306916251724}
inputPromptObject: {fileID: 844544797351374585}
inputPromptText: {fileID: 4622934279017998176}
--- !u!1 &5990189277179061188 --- !u!1 &5990189277179061188
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1125,6 +1266,8 @@ GameObject:
- component: {fileID: 4969722040546674666} - component: {fileID: 4969722040546674666}
- component: {fileID: 134193338904535592} - component: {fileID: 134193338904535592}
- component: {fileID: 239521969410047457} - component: {fileID: 239521969410047457}
- component: {fileID: 5839081052582000735}
- component: {fileID: 3511617315799540544}
m_Layer: 5 m_Layer: 5
m_Name: HpText m_Name: HpText
m_TagString: Untagged m_TagString: Untagged
@@ -1249,6 +1392,44 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &5839081052582000735
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6311144745162350469}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 4969722040546674666}
generateReference: 0
variableName: hpTextRectTransform
- component: {fileID: 134193338904535592}
generateReference: 0
variableName: hpTextCanvasRenderer
- component: {fileID: 239521969410047457}
generateReference: 0
variableName: hpTextTextMeshProUGUI
- component: {fileID: 3511617315799540544}
generateReference: 1
variableName: hpFormatText
--- !u!114 &3511617315799540544
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6311144745162350469}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2efdcd06cdaa830448f76b22ea7c98fb, type: 3}
m_Name:
m_EditorClassIdentifier:
key: HUDHpText
--- !u!1 &6718941606657889011 --- !u!1 &6718941606657889011
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1260,6 +1441,7 @@ GameObject:
- component: {fileID: 716378031281921353} - component: {fileID: 716378031281921353}
- component: {fileID: 3543496471495762840} - component: {fileID: 3543496471495762840}
- component: {fileID: 4547091306916251724} - component: {fileID: 4547091306916251724}
- component: {fileID: 5196414089076549728}
m_Layer: 5 m_Layer: 5
m_Name: LevelCountdown m_Name: LevelCountdown
m_TagString: Untagged m_TagString: Untagged
@@ -1384,6 +1566,28 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &5196414089076549728
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6718941606657889011}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 716378031281921353}
generateReference: 0
variableName: levelCountdownRectTransform
- component: {fileID: 3543496471495762840}
generateReference: 0
variableName: levelCountdownCanvasRenderer
- component: {fileID: 4547091306916251724}
generateReference: 1
variableName: countdownText
--- !u!1 &6730857398932861040 --- !u!1 &6730857398932861040
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1395,6 +1599,8 @@ GameObject:
- component: {fileID: 7063504788097480022} - component: {fileID: 7063504788097480022}
- component: {fileID: 6366053473665816812} - component: {fileID: 6366053473665816812}
- component: {fileID: 1751630811530388523} - component: {fileID: 1751630811530388523}
- component: {fileID: 7322939721948672541}
- component: {fileID: 2782782041585949375}
m_Layer: 5 m_Layer: 5
m_Name: ExpText m_Name: ExpText
m_TagString: Untagged m_TagString: Untagged
@@ -1519,6 +1725,44 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &7322939721948672541
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6730857398932861040}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 7063504788097480022}
generateReference: 0
variableName: expTextRectTransform
- component: {fileID: 6366053473665816812}
generateReference: 0
variableName: expTextCanvasRenderer
- component: {fileID: 1751630811530388523}
generateReference: 0
variableName: expTextTextMeshProUGUI
- component: {fileID: 2782782041585949375}
generateReference: 1
variableName: expFormatText
--- !u!114 &2782782041585949375
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6730857398932861040}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2efdcd06cdaa830448f76b22ea7c98fb, type: 3}
m_Name:
m_EditorClassIdentifier:
key: HUDExpText
--- !u!1 &7553274491524383503 --- !u!1 &7553274491524383503
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1566,6 +1810,8 @@ GameObject:
- component: {fileID: 3637160362095897130} - component: {fileID: 3637160362095897130}
- component: {fileID: 8788606425707752593} - component: {fileID: 8788606425707752593}
- component: {fileID: 1716982582738894949} - component: {fileID: 1716982582738894949}
- component: {fileID: 7818830623860974121}
- component: {fileID: 40991353312457281}
m_Layer: 5 m_Layer: 5
m_Name: Text (TMP) m_Name: Text (TMP)
m_TagString: Untagged m_TagString: Untagged
@@ -1690,6 +1936,44 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &7818830623860974121
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8499455344539348579}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 3637160362095897130}
generateReference: 0
variableName: textTMPRectTransform
- component: {fileID: 8788606425707752593}
generateReference: 0
variableName: textTMPCanvasRenderer
- component: {fileID: 1716982582738894949}
generateReference: 0
variableName: textTMPTextMeshProUGUI
- component: {fileID: 40991353312457281}
generateReference: 1
variableName: enemyCountFormatText
--- !u!114 &40991353312457281
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8499455344539348579}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2efdcd06cdaa830448f76b22ea7c98fb, type: 3}
m_Name:
m_EditorClassIdentifier:
key: HUDEnemyCountText
--- !u!1 &8883820757741353608 --- !u!1 &8883820757741353608
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1701,6 +1985,8 @@ GameObject:
- component: {fileID: 5394394129721257420} - component: {fileID: 5394394129721257420}
- component: {fileID: 7988281595709803232} - component: {fileID: 7988281595709803232}
- component: {fileID: 3568634826224029446} - component: {fileID: 3568634826224029446}
- component: {fileID: 1437112477034048177}
- component: {fileID: 3804240423293578540}
m_Layer: 5 m_Layer: 5
m_Name: Text (TMP) m_Name: Text (TMP)
m_TagString: Untagged m_TagString: Untagged
@@ -1745,8 +2031,8 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Material: {fileID: 0} m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1 m_RaycastTarget: 1
@@ -1755,7 +2041,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_text: "CPU Frame: -- ms\nSimulation: -- ms\nJob Wait: -- ms\nGC Alloc: -- B/frame" m_text: 'CPU Frame: -- ms'
m_isRightToLeft: 0 m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 99d811b0183246646a2ce8df996f4bca, type: 2} m_fontAsset: {fileID: 11400000, guid: 99d811b0183246646a2ce8df996f4bca, type: 2}
m_sharedMaterial: {fileID: -1106088975554028259, guid: 99d811b0183246646a2ce8df996f4bca, m_sharedMaterial: {fileID: -1106088975554028259, guid: 99d811b0183246646a2ce8df996f4bca,
@@ -1825,3 +2111,41 @@ MonoBehaviour:
m_hasFontAssetChanged: 0 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &1437112477034048177
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8883820757741353608}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2efdcd06cdaa830448f76b22ea7c98fb, type: 3}
m_Name:
m_EditorClassIdentifier:
key: HUDCPUTimeCostText
--- !u!114 &3804240423293578540
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8883820757741353608}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 5394394129721257420}
generateReference: 0
variableName: textTMPRectTransform
- component: {fileID: 7988281595709803232}
generateReference: 0
variableName: textTMPCanvasRenderer
- component: {fileID: 3568634826224029446}
generateReference: 0
variableName: textTMPTextMeshProUGUI
- component: {fileID: 1437112477034048177}
generateReference: 1
variableName: cpuTimeCostFormatText

Some files were not shown because too many files have changed in this diff Show More