UI 系统
This commit is contained in:
@@ -30,9 +30,8 @@ namespace BaseGames.Editor.Debugging
|
||||
return;
|
||||
}
|
||||
|
||||
var save = ServiceLocator.GetOrDefault<ISaveService>();
|
||||
if (save != null && !save.HasSave(0))
|
||||
save.CreateSlot(0, false); // 建立内存存档,确保新游戏初始状态
|
||||
// 统一会话入口:建档(内部应用空档并广播初始值,HUD 正确填充)+ 应用难度。与正式新游戏共用。
|
||||
ServiceLocator.GetOrDefault<IGameSessionService>()?.BeginNewGame(0, DifficultyLevel.Normal);
|
||||
|
||||
// 必须经事件频道 EVT_SceneLoadRequest 发请求:SceneService 据此加载场景,
|
||||
// GameManager 据此驱动状态机 LoadingScene → Gameplay(HUD/小地图随之显示)。
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace BaseGames.Editor.UI
|
||||
|
||||
// ── HUDRoot ───────────────────────────────────────────────────────
|
||||
GameObject hudRootGo = GetOrCreateChild(canvasGo.transform, "HUDRoot").gameObject;
|
||||
StretchFull(hudRootGo.transform); // 铺满 Canvas,使子元件的四角锚定映射到真实屏幕角
|
||||
HUDController hudCtrl = GetOrAddComponent<HUDController>(hudRootGo);
|
||||
|
||||
// 若场景中已存在 UIManager,自动将 _hudRoot 指向本 HUDRoot
|
||||
@@ -72,11 +73,18 @@ namespace BaseGames.Editor.UI
|
||||
// ── 形态图标(Form Icons × 4)────────────────────────────────────
|
||||
const int kFormIconCount = 4;
|
||||
GameObject formIconsRoot = GetOrCreateChild(hudRootGo.transform, "FormIcons").gameObject;
|
||||
var formLayout = GetOrAddComponent<HorizontalLayoutGroup>(formIconsRoot);
|
||||
formLayout.childForceExpandWidth = false;
|
||||
formLayout.childForceExpandHeight = false;
|
||||
formLayout.spacing = 6f;
|
||||
Image[] formImages = new Image[kFormIconCount];
|
||||
for (int i = 0; i < kFormIconCount; i++)
|
||||
{
|
||||
GameObject iconGo = GetOrCreateChild(formIconsRoot.transform, $"FormIcon_{i}").gameObject;
|
||||
formImages[i] = GetOrAddComponent<Image>(iconGo);
|
||||
var le = GetOrAddComponent<LayoutElement>(iconGo);
|
||||
le.preferredWidth = 40f;
|
||||
le.preferredHeight = 40f;
|
||||
}
|
||||
|
||||
// ── 交互提示(InteractPrompt)─────────────────────────────────────
|
||||
@@ -242,6 +250,25 @@ namespace BaseGames.Editor.UI
|
||||
|
||||
AssignAsset(toolHUD, "_onToolUsed", report, false, "EVT_ToolUsed");
|
||||
|
||||
// ── 布局摆位(点锚定到屏幕四角,避免元件堆叠在中心;尺寸/留白为占位,美术可再精修)──
|
||||
// 左上角:战斗信息簇(血条 / 魄元 / 灵力 / 灵泉 / 形态 / 灵铢 / 状态效果,自上而下)
|
||||
SetRect(hpContainerGo.transform, TopLeft, TopLeft, new Vector2(40f, -40f), new Vector2(500f, 50f));
|
||||
SetRect(soulGaugeGo.transform, TopLeft, TopLeft, new Vector2(40f, -100f), new Vector2(240f, 22f));
|
||||
SetRect(spiritGaugeGo.transform, TopLeft, TopLeft, new Vector2(40f, -128f), new Vector2(240f, 22f));
|
||||
SetRect(springContainerGo.transform, TopLeft, TopLeft, new Vector2(40f, -160f), new Vector2(240f, 32f));
|
||||
SetRect(formIconsRoot.transform, TopLeft, TopLeft, new Vector2(40f, -200f), new Vector2(240f, 44f));
|
||||
SetRect(lingZhuGo.transform, TopLeft, TopLeft, new Vector2(40f, -252f), new Vector2(200f, 40f));
|
||||
SetRect(statusHUDGo.transform, TopLeft, TopLeft, new Vector2(40f, -300f), new Vector2(320f, 44f));
|
||||
// 顶部居中:Boss 血条(默认隐藏)
|
||||
SetRect(bossBarGo.transform, TopCenter, TopCenter, new Vector2(0f, -40f), new Vector2(720f, 60f));
|
||||
// 右上角:任务追踪
|
||||
SetRect(questTrackerGo.transform, TopRight, TopRight, new Vector2(-40f, -40f), new Vector2(320f, 220f));
|
||||
// 右下角:法术槽 + 工具栏
|
||||
SetRect(spellSlotGo.transform, BottomRight, BottomRight, new Vector2(-40f, 40f), new Vector2(90f, 90f));
|
||||
SetRect(toolHUDGo.transform, BottomRight, BottomRight, new Vector2(-150f, 40f), new Vector2(180f, 90f));
|
||||
// 底部居中:交互提示
|
||||
SetRect(interactPromptGo.transform, BottomCenter, BottomCenter, new Vector2(0f, 140f), new Vector2(320f, 64f));
|
||||
|
||||
// ── 手工步骤说明 ──────────────────────────────────────────────────
|
||||
// _hpCellPrefab / _springIconPrefab 已自动创建并绑定(占位红/青方块,美术可替换)。
|
||||
report.Add("BossHPBar._phaseMarkerPrefab:请将阶段标记点 Prefab 赋给该字段。");
|
||||
@@ -352,12 +379,47 @@ namespace BaseGames.Editor.UI
|
||||
Transform child = parent.Find(name);
|
||||
if (child != null) return child;
|
||||
|
||||
GameObject go = new GameObject(name);
|
||||
// UI 节点必须是 RectTransform:new GameObject 默认创建普通 Transform,
|
||||
// 仅当随后挂上 Graphic/LayoutGroup 时才会被隐式转换——纯逻辑容器(FormIcons / SpellSlot 等)
|
||||
// 会停留为普通 Transform 而无法锚定/定位。显式带 RectTransform 创建,杜绝该缺陷。
|
||||
GameObject go = new GameObject(name, typeof(RectTransform));
|
||||
Undo.RegisterCreatedObjectUndo(go, $"Create {name}");
|
||||
go.transform.SetParent(parent, false);
|
||||
return go.transform;
|
||||
}
|
||||
|
||||
// ── 锚定 / 布局 ───────────────────────────────────────────────────────
|
||||
/// <summary>设置 RectTransform 的锚点 / 轴心 / 锚定坐标 / 尺寸(统一布局入口)。</summary>
|
||||
private static void SetRect(Transform t, Vector2 anchor, Vector2 pivot, Vector2 anchoredPos, Vector2 size)
|
||||
{
|
||||
var rt = t as RectTransform;
|
||||
if (rt == null) return;
|
||||
rt.anchorMin = anchor;
|
||||
rt.anchorMax = anchor;
|
||||
rt.pivot = pivot;
|
||||
rt.sizeDelta = size;
|
||||
rt.anchoredPosition = anchoredPos;
|
||||
}
|
||||
|
||||
/// <summary>将 RectTransform 设为全屏拉伸(铺满父节点,offset 全 0)。用于 HUDRoot 等容器根。</summary>
|
||||
private static void StretchFull(Transform t)
|
||||
{
|
||||
var rt = t as RectTransform;
|
||||
if (rt == null) return;
|
||||
rt.anchorMin = Vector2.zero;
|
||||
rt.anchorMax = Vector2.one;
|
||||
rt.pivot = new Vector2(0.5f, 0.5f);
|
||||
rt.offsetMin = Vector2.zero;
|
||||
rt.offsetMax = Vector2.zero;
|
||||
}
|
||||
|
||||
// 常用锚/轴心常量(点锚定,非拉伸)
|
||||
private static readonly Vector2 TopLeft = new(0f, 1f);
|
||||
private static readonly Vector2 TopCenter = new(0.5f, 1f);
|
||||
private static readonly Vector2 TopRight = new(1f, 1f);
|
||||
private static readonly Vector2 BottomRight = new(1f, 0f);
|
||||
private static readonly Vector2 BottomCenter= new(0.5f, 0f);
|
||||
|
||||
private static T GetOrAddComponent<T>(GameObject go) where T : Component
|
||||
{
|
||||
T c = go.GetComponent<T>();
|
||||
|
||||
Reference in New Issue
Block a user