UI系统优化

This commit is contained in:
2026-05-25 11:54:37 +08:00
parent c7057db27d
commit 3c812cfb41
130 changed files with 4738 additions and 477 deletions

View File

@@ -1,9 +1,11 @@
using System.Collections.Generic;
using UnityEngine;
using BaseGames.Localization;
namespace BaseGames.Dialogue
{
/// <summary>
/// 对话角色定义 SO(架构 14_NarrativeModule §3
/// (架构 14_NarrativeModule §3
/// 将 NPC 的显示名、头像、对话气泡颜色集中在一处管理。
/// DialogueLine.actor 引用此 SO修改头像/名称只需改一个资产,
/// 无需批量编辑所有对话行。
@@ -11,7 +13,7 @@ namespace BaseGames.Dialogue
/// 资产路径Assets/_Game/Data/Dialogue/Actors/Actor_{actorId}.asset
/// </summary>
[CreateAssetMenu(menuName = "BaseGames/Dialogue/DialogueActor")]
public class DialogueActorSO : ScriptableObject
public class DialogueActorSO : ScriptableObject, ILocalizableAsset
{
[Header("标识")]
[Tooltip("唯一 ID如 \"NPC_Elder\",供 DialogueLine 引用")]
@@ -77,5 +79,11 @@ namespace BaseGames.Dialogue
}
}
#endif
public IEnumerable<LocalizationKeyRef> GetLocalizationKeys()
{
if (!string.IsNullOrEmpty(nameKey))
yield return new LocalizationKeyRef(nameKey, "Dialogue", nameof(nameKey));
}
}
}

View File

@@ -1,5 +1,7 @@
using System.Collections.Generic;
using UnityEngine;
using BaseGames.Core;
using BaseGames.Localization;
namespace BaseGames.Dialogue
{
@@ -80,7 +82,7 @@ namespace BaseGames.Dialogue
/// 资产路径: Assets/ScriptableObjects/Dialogue/DLG_{NpcId}_{Context}.asset
/// </summary>
[CreateAssetMenu(menuName = "BaseGames/Dialogue/DialogueSequence")]
public class DialogueSequenceSO : ScriptableObject
public class DialogueSequenceSO : ScriptableObject, ILocalizableAsset
{
[Header("标识")]
[Tooltip("序列唯一 ID如 \"DLG_Elder_Quest_Available\"。OnValidate 会自动以资产名填充,也可手动指定。")]
@@ -320,5 +322,22 @@ namespace BaseGames.Dialogue
return false;
}
#endif
public IEnumerable<LocalizationKeyRef> GetLocalizationKeys()
{
if (lines == null) yield break;
foreach (var line in lines)
{
if (!string.IsNullOrEmpty(line.textKey))
yield return new LocalizationKeyRef(line.textKey, "Dialogue", "lines.textKey");
// speakerNameKey only relevant when actor is absent (override path)
if (line.actor == null && !string.IsNullOrEmpty(line.speakerNameKey))
yield return new LocalizationKeyRef(line.speakerNameKey, "Dialogue", "lines.speakerNameKey");
if (line.choices != null)
foreach (var choice in line.choices)
if (!string.IsNullOrEmpty(choice.textKey))
yield return new LocalizationKeyRef(choice.textKey, "Dialogue", "lines.choices.textKey");
}
}
}
}

View File

@@ -90,7 +90,7 @@ namespace BaseGames.Dialogue
bool hasSpeaker = !string.IsNullOrEmpty(resolvedNameKey);
if (_speakerNamePanel != null) _speakerNamePanel.SetActive(hasSpeaker);
if (hasSpeaker && _speakerNameText != null)
_speakerNameText.text = LocalizationManager.Get(resolvedNameKey, "Dialogue");
_speakerNameText.text = LocalizationManager.Get(resolvedNameKey, LocalizationTable.Dialogue);
// 说话人名称框背景颜色accentColor有 actor 时着色,无 actor 时还原默认色
if (_speakerNameBackground != null)
@@ -145,7 +145,7 @@ namespace BaseGames.Dialogue
}
else
{
_dialogueText.text = LocalizationManager.Get(key, "Dialogue");
_dialogueText.text = LocalizationManager.Get(key, LocalizationTable.Dialogue);
}
}
IsTyping = false;
@@ -200,7 +200,7 @@ namespace BaseGames.Dialogue
var (go, btn, lbl) = _choicePool[i];
go.SetActive(true);
if (lbl != null)
lbl.text = LocalizationManager.Get(choices[i].textKey ?? "", "Dialogue");
lbl.text = LocalizationManager.Get(choices[i].textKey ?? "", LocalizationTable.Dialogue);
if (btn != null)
{
btn.onClick.RemoveAllListeners();
@@ -253,7 +253,7 @@ namespace BaseGames.Dialogue
}
else
{
text = LocalizationManager.Get(line.textKey, "Dialogue");
text = LocalizationManager.Get(line.textKey, LocalizationTable.Dialogue);
}
// 复用缓存 StringBuilder避免每行 new 分配TMP SetText(StringBuilder) 零分配

View File

@@ -39,7 +39,7 @@ namespace BaseGames.Dialogue
{
if (!string.IsNullOrEmpty(_interactPromptKey))
{
var resolved = LocalizationManager.Get(_interactPromptKey, "UI");
var resolved = LocalizationManager.Get(_interactPromptKey, LocalizationTable.UI);
if (!string.IsNullOrEmpty(resolved)) return resolved;
}
return "对话";
@@ -81,7 +81,11 @@ namespace BaseGames.Dialogue
}
// ── 子类覆盖点 ──────────────────────────────────────────────────────
/// <summary>组件启用时调用。子类可覆盖且应调用 base.OnEnable()。</summary>
protected virtual void OnEnable() { }
/// <summary>组件禁用时调用。子类可覆盖且应调用 base.OnDisable()。</summary>
protected virtual void OnDisable() { }
/// <summary>交互前置逻辑(如任务接收/完成判断)。子类覆盖此方法。</summary>
protected virtual void Interact_Internal(Transform player) { }

View File

@@ -73,6 +73,9 @@ namespace BaseGames.Dialogue
private void Update()
{
// 完全隐藏且不需要淡出时,跳过所有计算
if (!_visible && _alpha <= 0f) return;
// 位置偏移(世界空间气泡)
if (_offset != Vector3.zero)
transform.position = (_npc != null ? _npc.transform.position : transform.parent.position) + _offset;

View File

@@ -1,4 +1,6 @@
using System.Collections.Generic;
using UnityEngine;
using BaseGames.Localization;
namespace BaseGames.Dialogue
{
@@ -14,7 +16,7 @@ namespace BaseGames.Dialogue
/// 资产路径Assets/_Game/Data/NPC/NPC_{npcId}.asset
/// </summary>
[CreateAssetMenu(menuName = "BaseGames/NPC/NPC")]
public class NpcSO : ScriptableObject
public class NpcSO : ScriptableObject, ILocalizableAsset
{
[Header("标识")]
[Tooltip("NPC 唯一 ID如 \"NPC_Elder\"。需与 InteractableNPC._npcId 保持一致。")]
@@ -90,5 +92,14 @@ namespace BaseGames.Dialogue
}
}
#endif
public IEnumerable<LocalizationKeyRef> GetLocalizationKeys()
{
string table = string.IsNullOrEmpty(localizationTable) ? "UI" : localizationTable;
if (!string.IsNullOrEmpty(nameKey))
yield return new LocalizationKeyRef(nameKey, table, nameof(nameKey));
if (!string.IsNullOrEmpty(interactPromptKey))
yield return new LocalizationKeyRef(interactPromptKey, "UI", nameof(interactPromptKey));
}
}
}