【UE 网络】Network Role and Authority、Actors Owner、Actor Role and RemoteRole
UE 网络核心概念完整理解文档
目标:用工程视角一次性理解 UE 网络中最容易混淆的概念,并知道什么时候用、怎么用、怎么不踩坑。
一、UE 网络的总体模型(先有大图)
1. 权威模型(Server-Authority)
服务器(Server)是唯一权威
-
所有“会影响游戏结果”的数据:
- 只能在 Server 改
- Client 只能请求
一句话:
Client 不能做决定,只能提请求;Server 负责裁决并同步结果
二、Network Role & Authority(谁说了算)
1. Authority(是否有裁决权)
-
HasAuthority()为true:- 当前对象在 Server 上
- 可以修改 Replicated 数据
-
HasAuthority()为false:- 当前在 Client
- 不能直接改状态
if (HasAuthority())
{
Health -= 10; // 正确
}
记忆:能不能改数据,看 Authority
三、Actor Role / RemoteRole(我是谁 & 别人怎么看我)
1. Role 是“本机视角”
| Role | 含义 |
|---|---|
| ROLE_Authority | 服务器上的 Actor |
| ROLE_AutonomousProxy | 本地玩家自己控制的 Actor |
| ROLE_SimulatedProxy | 别的玩家的 Actor |
2. 一个玩家 A / B 的例子
-
在 服务器:
- A.Character.Role = Authority
- B.Character.Role = Authority
-
在 A 客户端:
- A.Character.Role = AutonomousProxy
- B.Character.Role = SimulatedProxy
-
在 B 客户端:
- B.Character.Role = AutonomousProxy
- A.Character.Role = SimulatedProxy
3. 实战建议
- ❌ 不要用 Role 判断“是不是自己”
- ✅ 用:
IsLocallyControlled()
四、Actor Owner(这是谁的)
1. Owner 是什么?
Owner 表示逻辑归属,不等于 Authority
常见关系:
PlayerController
└─ Pawn / Character
└─ Weapon / SkillActor / UI驱动Actor
2. Owner 的 3 个核心用途
① Client RPC 路由
Client_ShowUI(); // 只发给 Owner
② resp_/OnRep 中判断“是不是我自己的”
if self:GetOwner() == LocalPlayerController then
-- 本地 UI / 私有逻辑
end
③ 网络相关性(Relevancy)
-
Owner 的 Actor:
- 永远对 Owner 同步
- 距离再远也可见
五、PlayerState / GameState 的本质区别
| 类 | 是否服务器权威 | 是否同步给所有客户端 | 用途 |
|---|---|---|---|
| GameMode | 是 | 否 | 规则裁判 |
| GameState | 是 | 是 | 全局公共信息 |
| PlayerState | 是 | 是 | 玩家公共状态 |
| PlayerController | 是 | 否 | 本地控制 & UI |
关键结论
PlayerState 的 OnRep / resp_ 会在所有客户端执行
这是设计目标,不是 Bug。
六、RPC 三兄弟(最重要)
1. Server RPC(Client → Server)
- 谁能调用:Client
- 在哪执行:Server
- 是否影响其他 Client:❌ 不直接影响
Server_RequestExitTower();
2. Client RPC(Server → Owner Client)
- 谁能调用:Server
- 在哪执行:指定 Client(Owner)
- 用途:UI / 本地提示
Client_ShowExitButton();
3. Multicast RPC(Server → 所有人)
- 谁能调用:Server
- 在哪执行:Server + 所有 Client
- 用途:特效 / 演出
NetMulticast_PlayEffect();
七、为什么“别的客户端感觉被影响了”?
根因只有一个:
不是 RPC 影响了别人,而是服务器“同步了结果”
常见来源:
- Server 修改了 Replicated 变量
- PlayerState 的 resp_ 在所有客户端触发
- 使用了 Multicast RPC
八、resp_ / OnRep 的正确使用姿势
错误示例 ❌
function PlayerState:resp_IsInTower()
UIManager:ShowExitButton() -- 所有人都会执行
end
正确示例 ✅
function PlayerState:resp_IsInTower()
if self:GetOwner() ~= LocalPlayerController then
return
end
UIManager:ShowExitButton()
end
九、最重要的“放哪里”速查表
| 需求 | 正确位置 |
|---|---|
| 改游戏结果 | Server |
| 玩家公共信息 | PlayerState |
| 只给自己看的 UI | PlayerController |
| 所有人共享状态 | GameState |
| 客户端请求行为 | Server RPC |
十、三句终极总结(请背下来)
- Authority 决定能不能改
- Owner 决定这是谁的
- Replication 决定谁能看到结果
UE 网络不难,难的是“概念混用”。
只要位置放对,90% 的网络 Bug 会自然消失。