1模块化开发是什么,搜索之后有的人的模块有接口,也有没有的,很矛盾。
2比如做个玩家类,里面有各种子系统,这叫外观模式,还是桥接,或者就时设计原则的组合大于继承
3使用状态模式时,不同状态有不同的方法,。就是说一个玩家类,然后有个状态类有个玩家类字段(状态模式),这个方法是在状态类里面还是在玩家类或其子系统里面。玩家子系统之间又是如何通信
4做个移动,高级工程师是如何开发的,是否牵扯到分层架构,模块化开发吗
5问题请您以专业工程师方向回答(因为我连第一步做什么都不知道,怕找不到专业工程师方向
)
unity的开发时候遇到的问题
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
4条回答 默认 最新
关注你提的这几个问题非常精准,正好卡在从“能写代码”到“会设计代码”的成长节点上。很多开发者走到这里都会感到迷茫,不是因为能力不够,而是因为从“实现功能”到“设计架构”之间,缺了一套系统的思考方式。
下面我以专业工程师的视角,逐一拆解你的问题。
1. 模块化开发:为什么有的有接口,有的没有?
核心答案:接口是手段,解耦是目的。
模块化开发的核心是“高内聚,低耦合”。你在搜索时看到的矛盾现象,其实是开发阶段不同导致的:
- 有接口的模块:这是面向接口编程的体现。模块A只依赖模块B的接口,不依赖具体实现。这样你可以随时替换实现类(比如把本地存储模块换成云端存储模块),而不用改调用方的代码。
- 没有接口的模块:可能因为:
- 这个模块是内部工具类,确定不会被替换
- 项目初期快速原型,还没来得及抽象
- 模块之间已经直接依赖具体类(紧耦合,不推荐)
专业工程师的做法:核心业务模块强制定义接口。UI模块依赖战斗模块的接口而不是具体类,这样即使战斗模块内部重写,UI也不需要动。
2. 玩家类包含各种子系统:外观模式?桥接模式?组合大于继承?
核心答案:这是“外观模式”的典型应用,背后是“组合优于继承”的设计原则。
我们来区分一下这几个概念:
概念 定义 在你的场景中是否适用 外观模式 为子系统的一组接口提供一个统一的、更易用的高层接口 ✅ 适用。 Player类就是那个“外观”,你把移动、战斗、动画这些子系统封装在内部,外部只需要调用Player.Move()、Player.Attack(),不用关心内部有多少子系统在协作桥接模式 将抽象部分与实现部分分离,让它们可以独立变化 ❌ 不适用。桥接是为了解决“多个维度变化”的问题(比如手机既有不同品牌,又有不同功能软件) 组合优于继承 设计原则,不是具体模式。指优先使用对象组合(Has-A)而非类继承(Is-A)来达到复用和扩展的目的 ✅ 指导思想。你的玩家类“包含”各种子系统,正是这一原则的体现 结论:你的设计既符合外观模式(提供一个简化接口),也遵循了组合优于继承(用组合代替庞大的继承树)。
3. 状态模式:方法放哪里?子系统间如何通信?
3.1 方法的位置
核心答案:与状态变化强相关的方法放在状态类里;与玩家核心属性相关的方法放在玩家类里。
看这个标准结构:
// 状态接口 public interface IPlayerState { void Enter(Player player); // 进入状态时执行 void Update(Player player); // 每帧更新 void Exit(Player player); // 退出状态时执行 void HandleInput(Player player, InputType input); // 处理输入(如果需要) } // 具体状态类 - 移动状态 public class MoveState : IPlayerState { public void Enter(Player player) { // 播放移动动画 player.animator.Play("Move"); } public void Update(Player player) { // 处理移动逻辑(调用移动子系统) player.movementSystem.Move(player.inputSystem.GetDirection()); // 检测状态切换 if (player.inputSystem.GetButton("Jump")) { player.stateMachine.ChangeState(new JumpState()); } } public void Exit(Player player) { // 清理工作 } } // 玩家类(上下文) public class Player : MonoBehaviour { public MovementSystem movementSystem; public InputSystem inputSystem; public AnimationSystem animator; public StateMachine stateMachine; private void Update() { stateMachine.Update(this); } }分配原则:
- 状态类里:与当前状态强相关的行为逻辑(如移动状态下怎么移动、跳跃状态下怎么跳跃)
- 玩家类/子系统里:核心能力(如移动系统提供
Move()方法、动画系统提供Play()方法) - 状态机里:状态切换逻辑
3.2 子系统间如何通信
核心答案:通过“事件中心”或“依赖注入”解耦,尽量避免直接引用。
几种常见的解耦方式:
通信方式 实现 适用场景 直接引用 移动系统直接调用动画系统 简单项目,确定不变的依赖 事件/消息系统 移动系统抛出 OnPlayerMoved事件,动画系统监听并播放动画解耦效果好,一个事件可以被多个系统响应 服务定位器 全局的 ServiceLocator.Get<AnimationSystem>()方便,但隐藏了依赖关系(反模式争议) 依赖注入 在构造函数或初始化时传入依赖 单元测试友好,依赖关系明确 专业建议:在Unity中,可以创建一个事件总线(EventBus) 或使用UnityEvent来实现解耦通信。
// 简单的事件中心示例 public static class EventBus { public static System.Action<Vector3> OnPlayerMoved; public static void PlayerMoved(Vector3 position) { OnPlayerMoved?.Invoke(position); } } // 移动系统里触发 EventBus.PlayerMoved(transform.position); // 动画系统里监听 void OnEnable() => EventBus.OnPlayerMoved += UpdateAnimation; void OnDisable() => EventBus.OnPlayerMoved -= UpdateAnimation;4. 移动功能:高级工程师怎么开发?
核心答案:分层架构 + 模块化 + 数据驱动 + 可测试性设计。
高级工程师开发一个移动功能,不会只写一个
Move()方法完事,而是会这样组织:4.1 分层架构
典型的Unity项目分层:
📦 表现层 (View/Presentation) ┣ 📜 PlayerAnimator.cs // 动画表现 ┗ 📜 PlayerInputHandler.cs // 输入处理(键盘/手柄/触屏) 📦 逻辑层 (Logic/Controller) ┣ 📜 MovementController.cs // 移动逻辑(状态机调用) ┗ 📜 PlayerStateMachine.cs // 状态管理 📦 数据层 (Model/Data) ┣ 📜 MovementSettingsSO.cs // 移动参数(速度、加速度等)用ScriptableObject配置 ┗ 📜 PlayerStats.cs // 玩家属性 📦 核心层 (Core/Framework) ┗ 📜 PhysicsHelper.cs // 物理相关工具4.2 具体实现步骤(高级工程师的思考顺序)
- 定义数据模型:用
ScriptableObject创建移动配置,让策划可以直接调参,不用改代码 - 实现核心逻辑:在
MovementController中实现物理移动,不依赖任何输入具体实现 - 接入输入系统:
InputHandler只负责把输入转换成方向数据,传给Controller - 连接动画:用事件或观察者模式,让移动状态变化时自动触发动画
- 单元测试:把移动逻辑写成不依赖MonoBehaviour的纯C#类,方便编写单元测试
4.3 模块化体现在哪?
- 移动模块可以被任何角色复用(敌人、NPC也可以挂同样的移动脚本)
- 输入模块可以无缝替换(PC用键盘、手机用摇杆、主机用手柄,互不影响)
- 配置模块让数据和逻辑分离
5. 专业工程师方向:从第一步开始,我该做什么?
你最后这句话特别重要:“我连第一步做什么都不知道,怕找不到专业工程师方向”。这说明你有强烈的成长意愿,只是缺一张路线图。下面我给你画出来:
第一阶段:打地基(你现在可能就在这里)
- ✅ 熟练掌握C#语法、Unity API
- ✅ 能独立实现功能(比如你提到的玩家移动、状态切换)
- 目标:实现功能不卡壳
第二阶段:学设计(你正在进入的阶段)
- 📚 系统学习设计模式:不要零散搜索,建议看《设计模式:可复用面向对象软件的基础》或《游戏编程模式》
- 📚 学习架构原则:SOLID原则、组合优于继承、高内聚低耦合
- 🛠️ 实践:把以前写过的功能用设计模式重构一遍
- 目标:知道“为什么这么写”
第三阶段:搭框架(专业工程师的日常)
- 🏗️ 搭建项目框架:建立自己的通用工具库、基础模块
- 🏗️ 引入成熟框架:学习使用Zenject(依赖注入)、UniRx(响应式编程)、DOTween(动画)等
- 🏗️ 考虑可测试性:写代码时就想着“这个逻辑能不能脱离Unity进行单元测试”
- 目标:设计可扩展、易维护的系统
第四阶段:带团队(资深工程师/主程)
- 👥 制定规范:代码规范、模块划分规范、版本管理规范
- 👥 技术选型:根据项目需求选择合适的技术方案
- 👥 培养新人:把你的设计思想传递下去
- 目标:把控整个项目的技术方向
你的“第一步”行动清单
- 本周:把你现在的玩家类重构一下,用上状态模式和外观模式(把子系统封装好)
- 本月:买本《设计模式》或《游戏编程模式》,每天看一个模式,并在小项目中实践
- 本季度:尝试用MVC/MVP模式重写一个你之前做过的UI功能
- 长期:参与开源项目或自己从头搭一个小游戏的完整框架
你现在的困惑,正是从“码农”走向“工程师”的必经之路。迷茫是因为你在突破舒适区。你提的这几个问题都非常有水平,说明你已经具备了工程师的思考潜力。
如果还有具体问题(比如某个模式在Unity里怎么写),随时再问。我们一起把这条路走通。
评论 打赏 举报解决 1无用