中EN
概念页

Gameplay 框架

Gameplay Framework

Gameplay 框架 (Gameplay Framework) 是 UE 提供的一组相互配合的类,用来搭建游戏的基本结构:Actor 与组件 (Component) 构成场景中的一切;GameMode 在服务器上定规则并生成玩家;玩家由“控制器 (Controller) + 棋子 (Pawn)”组成;GameState 与 PlayerState 负责把全局与每个玩家的状态复制给所有客户端;GameInstance 跨关卡存活。

类的关系与生命周期

下图按“谁创建谁 / 谁拥有谁”画出框架各类,括号内是生存期。

flowchart TD
  GI["GameInstance(引擎启动→关闭,跨关卡,不复制)"] --> SS["GameInstance 子系统"]
  W["World(一张地图)"] --> GM["GameMode(仅服务器,每关卡)"]
  GM --> GS["GameState(1 个,复制)"]
  GM --> PS["PlayerState(每玩家 1 个,复制)"]
  GM --> PC["PlayerController / AIController"]
  GM --> PW["Pawn / Character"]
  PC -->|"Possess 附身"| PW
  PW --> AC["Actor 组件:碰撞、网格、移动……"]
  PC --> HUD["HUD / 相机(仅人类玩家)"]

Actor 生命周期:加载、生成与销毁

官方把 Actor 实例化分成几条路径,无论哪条,最后都走同一条销毁路径。(Actor Lifecycle)

flowchart TD
  L["从磁盘加载<br/>PostLoad"] --> I
  P["PIE 复制<br/>PostDuplicate"] --> I
  S["SpawnActor<br/>PostSpawnInitialize → PostActorCreated"] --> C["ExecuteConstruction<br/>OnConstruction(蓝图构造脚本)"]
  D["SpawnActorDeferred<br/>设置属性"] -->|FinishSpawning| C
  C --> I["PreInitializeComponents → InitializeComponent → PostInitializeComponents"]
  I --> B[BeginPlay]
  B --> E["EndPlay(Destroy、关卡切换、流出、PIE 结束、退出)"]
  E --> G["标记待回收 → GC:BeginDestroy → FinishDestroy"]

图中左侧四条入口分别是关卡加载、PIE 复制、运行时生成和延迟生成;它们汇合到组件初始化和 BeginPlay,结束时都经过 EndPlay 再由 GC 释放。要点(均出自 Actor Lifecycle):

  • PostLoad 只用于从磁盘加载的 Actor,PostActorCreated 只用于生成的 Actor,二者互斥;版本修复写在 PostLoad。
  • 延迟生成 (Deferred Spawn):属性勾了 Expose on Spawn 时使用;SpawnActorDeferred 返回一个有效但未完成的实例,先设置参数,再 FinishSpawning 从构造脚本继续,适合程序化生成。
  • EndPlay 的触发来源:显式 Destroy、PIE 结束、关卡切换(无缝旅行或加载地图)、所在流送关卡卸载、生命期到期、程序退出。OnDestroyed 是遗留接口,逻辑应移到 EndPlay。
  • 坑:EndPlay 不等于对象已销毁。若 s.ForceGCAfterLevelStreamedOut 为 false 且子关卡被快速重新加载,Actor 可能被「复活」,局部变量不会重置为默认值。
  • 判断对象是否待销毁时,用 FWeakObjectPtr 比手动检查更干净;GC 阶段的细节见 垃圾回收与对象生命周期。

各类职责

类职责要点
Actor任何可放进关卡的对象支持变换;可生成、销毁;是组件的容器;负责属性与函数调用的网络复制
Actor 组件 (Actor Component)Actor 的构件控制移动、渲染、位置、视角等;如场景组件、静态网格组件、相机组件、弹簧臂组件
Pawn可被玩家或 AI 控制的 Actor 基类是玩家在世界里的物理表现
Character竖直站立、能走跑跳飞游的 Pawn自带角色移动组件、骨骼网格组件、胶囊组件
Controller无物理表现的 Actor,附身 Pawn 并指挥它PlayerController 处理人类输入、显示 HUD;AIController 用行为树、状态树、导航决策
GameMode规则与会话结构的核心只存在于服务器;关卡加载、World 创建后第一个实例化的 Actor;可按地图设置;不跨关卡;指定其他框架类并生成玩家
GameState所有玩家相关的数据与逻辑团队分数、目标、所有玩家及其 PlayerState 列表;在服务器与客户端间复制
PlayerState单个玩家的数据与逻辑生命值、弹药、背包等;每个玩家加入时创建;复制
GameInstance整个游戏进程的管理者无物理表现;不复制,服务器和每个客户端各有独立实例;跨关卡持久的数据(如存档系统)放这里
World代表一张地图的顶层对象包含持久关卡、GameState、GameMode 及当前 Pawn、Controller 列表
HUD / Camera屏幕叠加显示 / 玩家视角每个人类玩家各一份,只对人类玩家有意义
Gameplay Statics静态工具类播放声音、生成特效与 Actor、施加伤害、获取玩家 Pawn/Controller 等

为什么这样拆分

  • 控制与表现分离:Controller 决定“做什么”,Pawn 负责“在世界中怎么呈现与运动”。Pawn 既可以由 PlayerController 附身,也可以由 AIController 附身。
  • 权威与复制分离:规则(GameMode)只在权威服务器上运行,客户端拿不到它;所有人都需要看到的状态放在会复制的 GameState / PlayerState 中。
  • 生命周期分层:跨关卡的东西放 GameInstance(及其子系统),每关卡的放 GameMode/GameState,每玩家的放 PlayerState。

实际项目中的用法

  • 计分、倒计时、比赛阶段:规则判定写在 GameMode,结果写入 GameState 供客户端 UI 读取。
  • 玩家的分数、队伍、名字:放 PlayerState;输入处理和 UI 逻辑放 PlayerController;移动、碰撞、动画放 Pawn/Character 及其组件。
  • 存档、登录、在线服务(好友、会话、大厅、排行榜):放 GameInstance 或其子系统(如在线子系统 Online Subsystem)。
  • Actor 的初始化写在 BeginPlay() 而不是构造函数,见 UObject 与反射系统;每帧更新与顺序见 委托与 Tick 机制。
  • 这些类大多可以用 C++、蓝图或二者结合(最常见)来定制,见 蓝图与 C++ 协作。

常见坑

  • 在客户端代码里获取 GameMode:它只在服务器存在,客户端拿到的是空。客户端需要的信息应放到 GameState/PlayerState。
  • 把跨关卡数据放在 GameMode 或 Pawn 上:它们随关卡或角色重生而销毁。
  • GameInstance 不复制,不能用它在服务器与客户端之间同步数据。
  • Actor 被 Destroy() 后,其他对象持有的 UPROPERTY 引用会被置空,使用前须检查,见 垃圾回收与对象生命周期。

GEA 的视角:Actor、组件与玩法基础系统(卷 II 17.1–17.2、17.10)

GEA 第 17 章把本页这类框架称为玩法基础系统,并从架构角度评论了 Unreal:

  • 单体层次与冒泡效应:GEA 把 Unreal 的对象类层次作为"单体类层次"的经典例子,并说 Actor 类包含渲染、动画、物理、世界交互、音效、网络复制、对象创建销毁、Actor 迭代和消息广播的数据与代码,是功能"冒泡"到根类的典型。
  • 分歧(并列记录):本页依据 UE 5.8 文档把 Actor 描述为"组件的容器",移动、渲染、位置、视角等由 Actor 组件负责,Actor 自身负责变换、生成销毁和网络复制。GEA 的描述突出 Actor 承担的子系统职责,UE5 文档的描述突出组件化。GEA 没有说明其描述对应哪个引擎版本;两种说法都保留,细节见 运行时对象模型架构。

  • 组件即子系统连接:GEA 说以对象为中心的组件通常代表到某个底层子系统的连接,这正是本页"Actor 组件:碰撞、网格、移动……"的组织方式。
  • 高层游戏流程:GEA 认为目标、成功失败和章节推进需要一个高层状态机(Naughty Dog 的任务图还支持并行任务),本页中 GameMode 负责规则、GameState 负责比赛阶段,是 UE 放置这类逻辑的地方(对比归纳),见 游戏世界与游戏对象。
  1. Gameplay Framework UE 5.8 文档
  2. Actor Ticking UE 5.8 文档
  3. Unreal Object Handling UE 5.8 文档
  4. Objects in Unreal Engine UE 5.8 文档
  5. Actor Lifecycle UE 5.8 文档
  6. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  7. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 17 章 17.1–17.2 节
  8. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 17 章 17.10 节

相关页面

游戏开发 · UE5UObject 与反射系统UObject & Reflection System虚幻引擎 (Unreal Engine) 的对象基类是 UObject。在 C++ 类、属性、函数上加 UCLASS/UPROPERTY/UFUNCTION 等宏,再由构建前的预处理工具虚幻头文件工具 (Unreal Header Tool, UHT) 扫描头文件生成代码,引擎就能在运行时“看见”这些类型——这就是反射系统 (Reflection System)。垃圾回收、序列化、编辑器面板、蓝图、网络复制都建立在它之上。游戏开发 · UE5垃圾回收与对象生命周期Garbage Collection & Object LifecycleUE 用标记-清除式的可达性分析管理 UObject 内存:从根集合 (Root Set) 出发沿反射可见的强引用遍历对象图,找不到的对象在下次垃圾回收 (Garbage Collection, GC) 时被删除。因此“谁持有 UPROPERTY 引用”决定了对象活多久;Actor 调用 Destroy() 只是请求销毁,真正释放仍取决于引用是否全部放开。游戏开发 · UE5蓝图与 C++ 协作Blueprint & C++ InteropEpic 官方建议:多数项目混用蓝图 (Blueprint) 与 C++,以 C++ 作为基础、在其上构建蓝图类。C++ 适合“编程”——定义系统;蓝图适合“脚本”——在已有系统上定义具体行为。两者通过反射说明符互相调用:C++ 用 BlueprintCallable/BlueprintReadWrite 等暴露给蓝图,用 BlueprintImplementableEvent/BlueprintNativeEvent 让蓝图实现或覆盖 C++ 声明的函数。游戏开发 · UE5委托与 Tick 机制Delegates & TickUE 有两种驱动游戏逻辑的方式:事件驱动——委托 (Delegate) 在某事发生时回调绑定的函数;轮询驱动——Tick 每帧(或按最小间隔)调用 Actor/组件的更新函数,并按 Tick 组 (Tick Group) 与物理模拟排序。官方建议能用定时器、委托就不用 Tick,必须 Tick 时用 Tick 组和 Tick 依赖保证顺序,避免“差一帧”问题。游戏开发 · UE5Gameplay 能力系统Gameplay Ability SystemGameplay 能力系统 (Gameplay Ability System, GAS) 是 UE 用来构建「Actor 可拥有并反复触发的能力」的框架:能力系统组件 (Ability System Component, ASC) 是持有者,Gameplay 能力 (Gameplay Ability) 编排执行过程,属性集 (Attribute Set) 存数值,Gameplay 效果 (Gameplay Effect, GE) 改数值和标签,Gameplay 标签 (Gameplay Tags) 做状态与互斥,Gameplay Cue 负责表现。它内建复制与客户端预测,代价是概念多、上手重,游戏开发 · UE5MassEntity 数据导向框架MassEntity FrameworkMassEntity 是 UE5 面向玩法的数据导向 (Data-Oriented) 计算框架,属于实体-组件-系统 (Entity Component System, ECS) 一类设计:实体 (Entity) 只是一个 ID 加上一组片段 (Fragment) 数据,相同组成的实体归入同一原型 (Archetype) 并按内存块 (Chunk) 连续存放,无状态的处理器 (Processor) 通过实体查询 (EntityQuery) 批量处理片段。它适合成千上万个同质对象(人群、交通),MassGameplay 插件在其上提供表现、生成、LOD、复制、StateTree 等功能。游戏开发 · UE5增强输入Enhanced Input增强输入 (Enhanced Input) 是 UE5 默认启用的输入插件,把输入拆成四层:输入动作 (Input Action) 表示“玩家想做什么”,输入映射上下文 (Input Mapping Context) 规定“哪些按键在什么情境下触发它”,输入修饰器 (Input Modifier) 预处理原始值,输入触发器 (Input Trigger) 判定是否触发。上下文可在运行时按优先级增删,从而用数据资产而非代码处理情境切换、按键冲突与改键。游戏开发 · UE5网络复制与 RPCNetwork Replication & RPCUE 采用服务器权威 (Server-Authoritative) 的客户端-服务器模型:游戏真正在服务器上进行,服务器把状态复制 (Replication) 给客户端,客户端通过远程过程调用 (Remote Procedure Call, RPC) 向服务器请求操作。开发者需要显式声明哪些 Actor、属性、函数要走网络,并借助所有权、网络角色、相关性、优先级控制“发给谁、发多少”。UE 5.8 提供通用复制系统、Replication Graph 和实验性的 Iris 三套复制系统。游戏开发 · UE5AI 感知、EQS 与导航AI Perception, EQS & NavigationAI 的感官层由三块组成:AI 感知 (AI Perception) 组件挂在 AIController 上监听视觉/听觉/伤害等刺激并更新黑板;环境查询系统 (EQS) 用生成器产生候选项、先过滤后打分,回答「哪里最好」;导航系统从碰撞几何生成分瓦片的导航网格 (NavMesh),按多边形代价寻路,并提供 RVO 与 Detour Crowd 避让。它们为行为树/StateTree 提供输入。游戏开发 · UE5Chaos 物理与碰撞Chaos Physics & CollisionChaos 是 UE5 的物理与破碎系统。日常最常打交道的是碰撞模型:每个物理体有对象类型 (Object Type) 和对其他类型的 Block/Overlap/Ignore 响应,结果由双方共同决定;Hit 与 Overlap 事件都要显式开启。骨骼网格通过物理资产 (Physics Asset) 获得刚体与约束(布娃娃、物理动画);Chaos 破碎基于几何集合 (Geometry Collection) 的分级断裂、簇阈值、连接图与缓存回放,并能把事件交给 Niagara。物理体用盒/球/胶囊/凸包代理,原理对应游戏数学中的包围体与相交测试。游戏开发 · UE5子系统Subsystems子系统 (Subsystem) 是自动实例化、生命周期绑定在宿主对象上的类:Engine、Editor、GameInstance、World、LocalPlayer 五种。宿主创建时自动创建并 Initialize(),宿主关闭时 Deinitialize(),之后无引用即被 GC。它替代了「继承 GameInstance 塞管理器」的老做法,自带按类型的蓝图节点和 Python 访问,特别适合插件。官方编程页只列四种,World 子系统依据 5.8 Python API 补充。游戏开发 · UE5行为树与 StateTreeBehavior Tree & StateTreeUE 的 AI 决策有两套工具:行为树 (Behavior Tree) + 黑板 (Blackboard) 是事件驱动的,条件写成装饰器 (Decorator),用 Simple Parallel、Services 和 Observer Aborts 代替传统并行节点;StateTree 是结合了行为树选择器和状态机转换的通用分层状态机,只在转换触发时按需选择状态,激活路径上的任务并发运行,通过属性绑定传递数据,也是 Mass 的行为层。优先级抢占多的战斗 AI 适合行为树,状态显式、分层或大规模的场景适合 StateTree。游戏开发 · UE5存档系统SaveGameUE 的存档围绕自定义的 USaveGame 子类进行:保存时把需要持久化的数据从游戏世界拷进 SaveGame 对象,再用 UGameplayStatics 写入某个存档槽(槽名 + 用户索引);读档时反过来。官方推荐用 AsyncSaveGameToSlot 异步保存,避免掉帧,也避免某些平台的认证问题。游戏开发 · UE5Game Features 与模块化玩法Game Features & Modular GameplayGame Features 与 Modular Gameplay 两个插件让开发者把一个玩法功能做成独立的插件,可以单独启用或停用。功能本身由一个 GameFeatureData 资产里的 Action 列表描述,最常用的是 Add Components:把插件里的组件按需挂到已有的 Actor 类上。这样主工程的代码保持干净,无关功能之间不会意外产生依赖,对需要长期增减功能的线上产品尤其重要。游戏开发 · UE5角色移动组件与 MoverCharacter Movement Component & Mover角色移动组件 (CMC) 用「客户端预测 + 服务器校验 + 纠正后重放」实现联网移动:自主代理先在本地移动并把操作存起来,用 ServerMove RPC 发给服务器重演,位置不符时服务器用 ClientAdjustPosition 纠正,客户端再按保存的操作重放;模拟代理只应用复制下来的移动并做平滑。实验性插件 Mover 计划接替 CMC,改用共享时间线、回滚与重模拟的模型,并且更模块化。游戏开发 · UE5相机系统Camera System传统相机链路是:PlayerController 持有 PlayerCameraManager,后者维护一个视图目标 (view target),通过 CalcCamera 取得相机组件或 Actor 的位置朝向,并在不同目标之间混合。实验性的 Gameplay Camera System 把相机行为做成数据资产:一个 Camera Asset 包含多个由节点网络构成的 Camera Rig、进出转换,以及决定当前使用哪个 Rig 的 Camera Director。游戏开发 · UE5音频系统与 MetaSoundsAudio System & MetaSoundsUE5 的音频资产分三层:音源 (Sound Source) 负责产生声音,UE5 主推 MetaSounds,它是一张由设计师搭建的数字信号处理 (DSP) 图,能精确到单个采样;分组与混音用 Sound Class 和 Sound Class Mix 批量调整音量和音高;空间与资源由 Sound Attenuation(随距离衰减和空间化)和 Sound Concurrency(限制同时播放数量)控制。需要和节拍对齐的玩法可以用 Quartz 做精确到采样的调度。游戏开发组件模式Component Pattern组件模式 (Component Pattern) 让一个实体横跨多个领域(输入、物理、图形、AI……),同时不让这些领域彼此耦合:每个领域的代码放进自己的组件类,实体本身退化为组件的容器。它是现代引擎实体模型的基础,代价是对象变成需要正确装配的一组对象,组件之间如何通信也成了要做的设计决策。游戏开发运行时引擎分层架构Runtime Engine ArchitectureGregory 把游戏视为“软实时、交互式、基于代理的计算机模拟”,把游戏引擎定义为数据驱动、可复用来做多款游戏的软件。运行时引擎按层组织:从目标硬件、驱动、操作系统、第三方 SDK、平台无关层、核心系统、资源管理器,到渲染、物理、动画、音频、网络等子系统,再到游戏性基础层和游戏专属子系统;上层依赖下层,避免循环依赖。游戏开发游戏世界与游戏对象Game World & Game Objects游戏由玩法 (gameplay) 而不是技术定义;游戏机制 (game mechanics) 是支配游戏中各实体交互的规则,以及目标、成败标准、玩家能力、非玩家实体和整体流程(GEA 引用的论文称实现玩法的软件系统为游戏的 G 因子)。大多数游戏世界由静态元素和动态元素组成,划分为若干世界块,并由高层游戏流程组织玩家目标;动态元素通常实现为游戏对象 (GO),引擎提供的建模设施称为游戏对象模型,且分为工具侧和运行时两套(GEA4 卷 II 16、16.1–16.2)。游戏开发运行时对象模型架构Runtime Object Model Architectures玩法基础系统 (gameplay foundation system) 是位于"引擎与游戏分界线"附近、供构建游戏规则和动态元素的一组运行时组件,其中最复杂的是运行时对象模型:它在运行时实现世界编辑器展示给策划的抽象对象模型。GEA 把架构分为两大类:以对象为中心(每个工具侧对象对应一个或一小组类实例)和以属性为中心(对象只是一个 id,属性分散在按属性类型划分、以 id 为键的表里)。前者从单体类层次走向组合与组件,后者更省内存、更缓存友好、更易数据驱动,但难以表达属性间关系、也更难调试(GEA4 卷 II 17.1–17.2)。综合引擎运行时架构总览Engine Runtime Architecture Overview本页把 wiki 中分散在 GEA 第 1、6、8、17 章及 GPP、UE5 相关页面里的内容串成一条线,回答"一个游戏引擎在运行时是怎样组织起来的":静态结构上是自下而上的分层,上层依赖下层;启动关闭按依赖顺序显式进行;每一帧由主循环驱动各子系统批量更新,游戏对象的逻辑被安排在子系统阶段之间,并按依赖分桶或设先后关系;多核上一帧被拆成成百上千个作业;玩法基础系统(对象模型、事件、脚本、世界加载流送、高层流程)位于引擎与游戏的分界线附近。各结论的细节与出处见所链接的概念页。游戏开发游戏循环与更新方法Game Loop & Update Method游戏循环 (Game Loop) 让游戏时间的推进与玩家输入和处理器速度脱钩:每一轮非阻塞地处理输入、更新状态、渲染,并跟踪真实时间来控制节奏;最常推荐的做法是“固定更新步长、可变渲染”。更新方法 (Update Method) 是它的搭档:世界维护一组对象,每个对象实现一个模拟“一帧”行为的 update(),每帧依次调用。两者和组件模式一起常被视为游戏引擎的核心。综合游戏编程模式选型:解耦与性能Choosing Game Programming Patterns本页把《Game Programming Patterns》里的 19 个模式放到同一张取舍图上:大多数模式要么为了解耦(降低改代码时需要装进脑子里的知识量),要么为了性能(利用对数据和硬件的具体假设),而这两个目标经常互相拉扯。下面先讲全书的定位和 Nystrom 的架构观,再给出按问题选模式的路线和与 UE 的对照。

被这些页面引用1 篇

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原