Files
Gen_Hack-and-Slash-Roguelite/Client/Assets/Scripts/UI/DevMenuUI.cs

212 lines
8.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Base;
using Data; // 确保 Data 命名空间包含 DefBase, CharacterDef, MonsterDef, BuildingDef, ItemDef, EventDef
using UnityEngine;
using UnityEngine.SceneManagement;
namespace UI
{
public class DevMenuUI : UIBase
{
public GameObject menuContent;
public EntityPlacementUI entityPlacementUI;
public Prefab.TextPrefab textTemplate;
public Prefab.ButtonPrefab buttonTemplate;
private void Start()
{
Init();
}
private void Init()
{
InitReloadGameButton();
InitEvent();
InitCharacter();
InitMonster();
InitBuilding();
InitItem();
InitWeapon();
}
private void InitReloadGameButton()
{
var button = InstantiatePrefab(buttonTemplate, menuContent.transform);
button.Label = "热重载Def";
button.AddListener(HotReload);
}
/// <summary>
/// 通用的初始化定义按钮的方法。
/// </summary>
/// <typeparam name="TDef">定义的类型,必须继承自 Data.DefBase。</typeparam>
/// <param name="titleLabel">菜单部分的标题。</param>
/// <param name="noDefMessage">当没有定义时显示的提示信息。</param>
/// <param name="buttonTextSelector">用于从 TDef 获取按钮显示文本的函数。</param>
/// <param name="buttonAction">点击按钮时执行的动作,传入对应的 TDef 对象。</param>
private void InitDefineButtons<TDef>(string titleLabel, string noDefMessage, System.Func<TDef, string> buttonTextSelector, System.Action<TDef> buttonAction) where TDef : Define
{
var title = InstantiatePrefab(textTemplate, menuContent.transform);
title.Label = titleLabel;
var defList = Managers.DefineManager.Instance.QueryNamedDefinesByType<TDef>();
if (defList == null || defList.Length == 0)
{
var noDefTitle = InstantiatePrefab(textTemplate, menuContent.transform);
noDefTitle.Label = noDefMessage;
noDefTitle.text.color = Color.red;
}
else
{
foreach (var def in defList)
{
var button = InstantiatePrefab(buttonTemplate, menuContent.transform);
button.Label = buttonTextSelector(def);
// 确保 lambda 捕获的是循环当前迭代的 def 变量,而不是循环变量本身
var currentDef = def;
button.AddListener(() => buttonAction(currentDef));
}
}
}
private void InitEvent()
{
// 假设存在 Data.EventDef 类型,且它继承自 Data.DefBase并包含一个可作为标签的字段。
// 如果事件触发逻辑不同于生成实体,需要在此处定义相应的回调。
InitDefineButtons<EventDef>(
"事件菜单",
"未定义任何事件",
// 假设 EventDef 也有 label 字段作为按钮文本
def => def.label,
eventDef =>
{
// TODO: 在这里实现事件触发逻辑
Debug.Log($"触发事件: {eventDef.label}");
// 示例: Managers.EventManager.Instance.TriggerEvent(eventDef.id);
});
}
private void InitCharacter()
{
InitDefineButtons<CharacterDef>(
"生成人物",
"未定义任何角色",
def => def.label,
GenerateEntityCallback);
}
private void InitMonster()
{
InitDefineButtons<MonsterDef>(
"生成怪物",
"未定义任何怪物",
def => def.label,
GenerateMonsterEntityCallback);
}
private void InitBuilding()
{
InitDefineButtons<BuildingDef>(
"生成建筑",
"未定义任何建筑",
def => def.label,
GenerateBuildingCallback);
}
private void InitItem()
{
InitDefineButtons<ItemDef>(
"生成掉落物",
"未定义任何物品",
def => def.label,
GeneratePickupCallback);
}
private void InitWeapon()
{
InitDefineButtons<WeaponDef>(
"生成武器",
"未定义任何武器",
def => def.label,
GeneratePickupCallback);
}
/// <summary>
/// 通用的实例化函数,返回实例化的预制件脚本组件。
/// </summary>
/// <typeparam name="T">预制件脚本的类型</typeparam>
/// <param name="prefab">要实例化的预制件</param>
/// <param name="parent">实例化对象的父对象</param>
/// <returns>实例化的预制件脚本组件</returns>
private T InstantiatePrefab<T>(T prefab, Transform parent) where T : Component
{
if (prefab == null || parent == null)
{
Debug.LogError("Prefab or parent is null!");
return null;
}
// 实例化预制件
var instance = Instantiate(prefab.gameObject, parent);
// 获取实例化对象的脚本组件
var instantiatedComponent = instance.GetComponent<T>();
if (instantiatedComponent == null)
{
Debug.LogError($"Failed to get component of type {typeof(T).Name} from the instantiated prefab!");
}
return instantiatedComponent;
}
private void GenerateEntityCallback(EntityDef entityDef)
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GenerateEntity(Program.Instance.FocusedDimensionId, entityDef, Utils.MousePosition.GetWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{entityDef.label}\n描述{entityDef.description}";
entityPlacementUI.snapEnabled = false;
UIInputControl.Instance.Show(entityPlacementUI);
}
private void GenerateMonsterEntityCallback(MonsterDef monsterDef)
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GenerateMonsterEntity(Program.Instance.FocusedDimensionId, monsterDef, Utils.MousePosition.GetWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{monsterDef.label}\n描述{monsterDef.description}";
entityPlacementUI.snapEnabled = false;
UIInputControl.Instance.Show(entityPlacementUI);
}
private void GenerateBuildingCallback(BuildingDef def)
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GenerateBuildingEntity(Program.Instance.FocusedDimensionId, def, Utils.MousePosition.GetSnappedWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{def.label}\n描述{def.description}";
entityPlacementUI.snapEnabled = true;
UIInputControl.Instance.Show(entityPlacementUI);
}
private void GeneratePickupCallback(ItemDef itemDef)
{
entityPlacementUI.currentAction = () =>
{
Managers.EntityManage.Instance.GeneratePickupEntity(Program.Instance.FocusedDimensionId, itemDef, Utils.MousePosition.GetWorldPosition());
};
entityPlacementUI.Prompt = $"当前生成器:\n名称{itemDef.label}\n描述{itemDef.description}";
entityPlacementUI.snapEnabled = false;
UIInputControl.Instance.Show(entityPlacementUI);
}
private void HotReload()
{
UIInputControl.Instance.HideAll();
Program.Instance.needLoad = true;
SceneManager.LoadScene(0);
}
}
}