嘿,每个人!
我正在工作于一个拼图/制作游戏,其中玩家探索 3D 世界,互动特定的工作站,并执行拖拽-放置网格谜题(放置/混合食材)。
我非常希望获得你对我规划的架构的意见和批评。我正在做这两种主要原因:以编写高度可维护的代码,并学习高级架构模式。因此,我想实施这一严格结构,即使它接近过度工程或增加复杂性。
以下是一些系统的高层级划分:
1. 输入和上下文切换(动作地图)
- 纯输入读者: 使用盲目广播规则,只读取硬件输入,引发 ScriptableObject(SO)事件(例如
OnInteractPressedSO,OnPointerClickSO)。这个脚本中没有任何逻辑或射线投影。 - 上下文切换: 在探索时,玩家世界的
Action Map是打开的。我使用IInteractable接口来实现世界对象。 - 转变: 当玩家触发一个工作站时,工作站触发
GameStateChangeSO事件。GameStateManager监听这个事件,将Action Map切换为Workstation(禁用玩家运动),释放鼠标光标,并启用工作站特有的控制器。
2. 数据vs视觉(主/从)
网格项(Ingredients)严格地分离了逻辑与视觉。数据类包含了一个Vector2Int来指示网格坐标(主),并在视觉类中使用Transform来匹配这些坐标(从)以避免任何浮点数同步问题。
3.拖拽放置和确认
- 库存管理员(数据所有者): 如果点击 UI(UI Toolkit)中的项,它会在 3D 世界中生成一个三维对象并引发
StartDraggingSO(item)`)。 - 拖拽管理员(运输者): 完全呆呆。它听到
StartDraggingSO,取出 3D 对象,并使用射线来跟踪鼠标位置。 - 放置确认: 当点击释放时,
DragManager使用射线进行检测。如果它击中了网格,会询问targetGrid.CanPlaceItem(item, coords)。 - 网格验证: 网格评估一个清单中的模块化
PlacementConditionSOs(例如,单元格是否为空?该项类型是否正确?)。 - 手拉手:
- 如果成功:网格会将项附着在上,引发
PlacementSuccessSO-->InventoryManager从数据池中移除该项。 - 如果失败(或在虚空中扔下):
DragManager引发PlacementFailedSO-->InventoryManager销毁 3D 虚拟物体,并恢复 UI Toolkit 图标。
目标
完全脱耦合。拖拽管理员不知道 UI,输入系统不知道食材是什么,玩家也不需要了解工作站内部的运作细节。
为我提出的问题:
- 在实践中,这将按预期工作吗?还是你预见到任何主要的瓶颈或过冲吗?
- 你是否能找到一种方法来简化这一架构,而仍能保持相同的脱耦合水平?
任何反馈、批评或建议都会倍受青睐。感谢!
https://preview.redd.it/znrnf80615zg1.png?width=2671&format=png&auto=webp&s=a3694c8961a603005a7217d8f61757951b184a80
评论 (0)