engine-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCross-Engine Design Patterns
跨引擎设计模式
A reference for implementing common game patterns across different engines. Use this when deciding on architecture or translating patterns between engines.
这是一份在不同引擎中实现常见游戏模式的参考文档,适用于架构决策或跨引擎模式转换场景。
Entity-Component-System (ECS)
实体-组件-系统(ECS)
How game objects are structured varies by engine:
| Engine | Model | Entity | Component | System |
|---|---|---|---|---|
| Unity | Component-Based | GameObject | MonoBehaviour | Manager scripts or DOTS Systems |
| Unreal | Actor-Component | AActor | UActorComponent | Tick functions or Subsystems |
| Godot | Node Tree | Node | Child Nodes | _process/_physics_process |
| Three.js | Scene Graph | Object3D | userData / custom classes | Game loop update functions |
| Orleans | Virtual Actor | Grain | Grain State / Interfaces | Grain methods + Timers |
When to use full ECS: Performance-critical systems with thousands of entities (Unity DOTS, custom ECS). For most gameplay, the engine's native component model is sufficient.
游戏对象的结构因引擎而异:
| 引擎 | 模型 | 实体 | 组件 | 系统 |
|---|---|---|---|---|
| Unity | 基于组件 | GameObject | MonoBehaviour | 管理器脚本或DOTS Systems |
| Unreal | Actor-Component | AActor | UActorComponent | Tick函数或子系统 |
| Godot | 节点树 | Node | 子节点 | _process/_physics_process |
| Three.js | 场景图 | Object3D | userData / 自定义类 | 游戏循环更新函数 |
| Orleans | 虚拟Actor | Grain | Grain State / 接口 | Grain方法 + 计时器 |
何时使用完整ECS:包含数千个实体的性能关键系统(如Unity DOTS、自定义ECS)。对于大多数游戏玩法,引擎原生的组件模型已足够。
State Machines
状态机
Every engine needs state machines for entities, game flow, and UI:
| Engine | Implementation |
|---|---|
| Unity | ScriptableObject-based states, or Animator for simple cases |
| Unreal | Gameplay Ability System, or custom UObject state classes |
| Godot | Node-based states as children of StateMachine node |
| Three.js | TypeScript classes with enter/exit/update methods |
| Orleans | Grain state + explicit transitions in grain methods |
Core pattern (all engines):
State {
enter() // Called when entering this state
exit() // Called when leaving this state
update(dt) // Called every frame while in this state
}
StateMachine {
currentState: State
transition(newState) {
currentState.exit()
newState.enter()
currentState = newState
}
}每个引擎都需要为实体、游戏流程和UI实现状态机:
| 引擎 | 实现方式 |
|---|---|
| Unity | 基于ScriptableObject的状态,或简单场景下使用Animator |
| Unreal | Gameplay Ability System,或自定义UObject状态类 |
| Godot | 基于节点的状态,作为StateMachine节点的子节点 |
| Three.js | 包含enter/exit/update方法的TypeScript类 |
| Orleans | Grain状态 + Grain方法中的显式状态转换 |
核心模式(所有引擎通用):
State {
enter() // 进入该状态时调用
exit() // 离开该状态时调用
update(dt) // 处于该状态时每帧调用
}
StateMachine {
currentState: State
transition(newState) {
currentState.exit()
newState.enter()
currentState = newState
}
}Observer/Event Pattern
观察者/事件模式
Decoupled communication between systems:
| Engine | Mechanism |
|---|---|
| Unity | C# events, UnityEvent, ScriptableObject event channels |
| Unreal | Delegates (DECLARE_DELEGATE), BlueprintAssignable events |
| Godot | Signals (built-in, first-class) |
| Three.js | EventDispatcher, custom EventEmitter, or RxJS |
| Orleans | Orleans Streams, IGrainObserver |
实现系统间的解耦通信:
| 引擎 | 机制 |
|---|---|
| Unity | C#事件、UnityEvent、ScriptableObject事件通道 |
| Unreal | 委托(DECLARE_DELEGATE)、BlueprintAssignable事件 |
| Godot | 信号(内置一等公民特性) |
| Three.js | EventDispatcher、自定义EventEmitter或RxJS |
| Orleans | Orleans Streams、IGrainObserver |
Object Pooling
对象池
Avoid allocation/deallocation overhead for frequently created objects:
| Engine | Strategy |
|---|---|
| Unity | Queue<GameObject>, SetActive(true/false) |
| Unreal | FActorPoolingSystem or custom TArray<AActor*> pool |
| Godot | Array of nodes, set visible/process_mode |
| Three.js | Array of Object3D, toggle visible property |
| Orleans | Not applicable (grains are virtual, always "exist") |
When to pool: Projectiles, particles, enemies, VFX, UI elements - anything created/destroyed frequently during gameplay.
避免频繁创建销毁对象带来的内存分配/释放开销:
| 引擎 | 策略 |
|---|---|
| Unity | Queue<GameObject>,调用SetActive(true/false) |
| Unreal | FActorPoolingSystem或自定义TArray<AActor*>池 |
| Godot | 节点数组,设置visible/process_mode |
| Three.js | Object3D数组,切换visible属性 |
| Orleans | 不适用(Grain是虚拟的,始终“存在”) |
何时使用对象池:投射物、粒子、敌人、视觉特效(VFX)、UI元素——任何在游戏过程中频繁创建/销毁的对象。
Networking Models
网络模型
| Engine | Built-in | Model |
|---|---|---|
| Unity | Netcode for GameObjects, Mirror, FishNet | Server-authoritative, client prediction |
| Unreal | Built-in replication | Server-authoritative, property replication, RPCs |
| Godot | MultiplayerPeer, MultiplayerSynchronizer | Server-authoritative or peer-to-peer |
| Three.js | None (use WebSocket/WebRTC) | Custom, typically server-authoritative |
| Orleans | Built-in (virtual actors) | Server-authoritative by design |
Core multiplayer principles:
- Server is authoritative - never trust client state
- Client predicts locally for responsiveness
- Server reconciles and corrects client state
- Use delta compression to minimize bandwidth
- Handle disconnection and reconnection gracefully
| 引擎 | 内置支持 | 模型 |
|---|---|---|
| Unity | Netcode for GameObjects、Mirror、FishNet | 服务器权威、客户端预测 |
| Unreal | 内置复制机制 | 服务器权威、属性复制、RPC |
| Godot | MultiplayerPeer、MultiplayerSynchronizer | 服务器权威或点对点 |
| Three.js | 无内置(使用WebSocket/WebRTC) | 自定义实现,通常为服务器权威 |
| Orleans | 内置(虚拟Actor) | 设计上默认服务器权威 |
多人游戏核心原则:
- 服务器拥有权威——绝不信任客户端状态
- 客户端本地预测以保证响应性
- 服务器协调并修正客户端状态
- 使用增量压缩最小化带宽消耗
- 优雅处理断开连接与重连
Save/Load Patterns
保存/加载模式
| Engine | Strategy |
|---|---|
| Unity | JsonUtility or custom serialization to PlayerPrefs/files |
| Unreal | USaveGame with UGameplayStatics::SaveGameToSlot |
| Godot | ConfigFile or custom JSON/Resource serialization |
| Three.js | JSON serialization to localStorage or server API |
| Orleans | Built-in grain persistence (automatic with IPersistentState) |
| 引擎 | 策略 |
|---|---|
| Unity | JsonUtility或自定义序列化到PlayerPrefs/文件 |
| Unreal | USaveGame结合UGameplayStatics::SaveGameToSlot |
| Godot | ConfigFile或自定义JSON/Resource序列化 |
| Three.js | JSON序列化到localStorage或服务器API |
| Orleans | 内置Grain持久化(结合IPersistentState自动实现) |
Input Abstraction
输入抽象
| Engine | System |
|---|---|
| Unity | New Input System (InputAction) or legacy Input class |
| Unreal | Enhanced Input System (UInputAction, UInputMappingContext) |
| Godot | InputMap with named actions, Input.is_action_pressed() |
| Three.js | Custom abstraction over DOM events (keyboard, mouse, gamepad API) |
Best practice: Map physical inputs to semantic actions ("jump", "attack", "interact"), never check raw keys in gameplay code.
| 引擎 | 系统 |
|---|---|
| Unity | New Input System(InputAction)或旧版Input类 |
| Unreal | Enhanced Input System(UInputAction、UInputMappingContext) |
| Godot | 带命名动作的InputMap,使用Input.is_action_pressed() |
| Three.js | 基于DOM事件(键盘、鼠标、游戏手柄API)的自定义抽象 |
最佳实践:将物理输入映射到语义动作(如“跳跃”、“攻击”、“交互”),绝不在游戏玩法代码中直接检测原始按键。
Audio Architecture
音频架构
| Engine | System |
|---|---|
| Unity | AudioSource + AudioListener, FMOD/Wwise for complex projects |
| Unreal | Sound Cues, MetaSounds (UE5), Wwise integration |
| Godot | AudioStreamPlayer2D/3D, AudioBus system |
| Three.js | Three.js AudioListener + PositionalAudio, or Howler.js |
| 引擎 | 系统 |
|---|---|
| Unity | AudioSource + AudioListener,复杂项目使用FMOD/Wwise |
| Unreal | Sound Cues、MetaSounds(UE5)、Wwise集成 |
| Godot | AudioStreamPlayer2D/3D、AudioBus系统 |
| Three.js | Three.js AudioListener + PositionalAudio,或Howler.js |
Physics
物理系统
| Engine | System | 2D | 3D |
|---|---|---|---|
| Unity | PhysX (3D), Box2D (2D) | Rigidbody2D, Collider2D | Rigidbody, Collider |
| Unreal | Chaos Physics | N/A (use Paper2D) | UPrimitiveComponent physics |
| Godot | GodotPhysics, Jolt | RigidBody2D, Area2D | RigidBody3D, Area3D |
| Three.js | None built-in | cannon-es, rapier2d | rapier3d, ammo.js |
| 引擎 | 系统 | 2D | 3D |
|---|---|---|---|
| Unity | PhysX(3D)、Box2D(2D) | Rigidbody2D、Collider2D | Rigidbody、Collider |
| Unreal | Chaos Physics | N/A(使用Paper2D) | UPrimitiveComponent物理 |
| Godot | GodotPhysics、Jolt | RigidBody2D、Area2D | RigidBody3D、Area3D |
| Three.js | 无内置 | cannon-es、rapier2d | rapier3d、ammo.js |
UI Architecture
UI架构
| Engine | System | Technology |
|---|---|---|
| Unity | UGUI (Canvas) or UI Toolkit | C# + XML (UI Toolkit) or Inspector-based |
| Unreal | UMG (Unreal Motion Graphics) | Blueprints + Slate (C++) |
| Godot | Control nodes (built-in) | Theme resources + GDScript |
| Three.js | HTML/CSS overlay or drei/Html | React components or DOM |
| 引擎 | 系统 | 技术栈 |
|---|---|---|
| Unity | UGUI(Canvas)或UI Toolkit | C# + XML(UI Toolkit)或基于Inspector |
| Unreal | UMG(Unreal Motion Graphics) | Blueprints + Slate(C++) |
| Godot | 内置Control节点 | Theme资源 + GDScript |
| Three.js | HTML/CSS叠加层或drei/Html | React组件或DOM |
Pattern Selection Guide
模式选择指南
For new projects, consider:
- Start with the engine's native patterns before adding frameworks
- Only add ECS when you have measurable performance needs
- Use the engine's built-in networking before rolling your own
- Prefer data-driven design for anything designers need to tune
- Keep architecture as simple as possible for the game's actual needs
对于新项目,建议:
- 在引入框架前先使用引擎原生模式
- 仅在有可衡量的性能需求时才引入ECS
- 在自行开发网络系统前优先使用引擎内置网络功能
- 对于设计师需要调整的内容,优先采用数据驱动设计
- 根据游戏实际需求保持架构尽可能简单