Unity插件-Mirror使用方法(十一)组件介绍(Network Room Player)
目录
一、插件介绍
二、主要组件
Network Manager
Network Manager HUD
Network Identity
Network Transform
Network Animator
Network Behaviour
Network Start Position
Network Room Manager
三、Network Room Player
1、组件介绍
2、核心功能
玩家状态同步
UI交互控制
生命周期管理
权限管理
3、关键属性与配置
4、基础使用步骤
步骤1:创建房间玩家预制体
步骤2:同步玩家状态
步骤3:房间玩家生命周期回调
5、高级功能与场景
1. 角色选择系统
2. 房主权限管理
3. 跨场景数据传递
6、常见问题与解决
7、最佳实践
UI与逻辑分离
输入验证
性能优化
扩展性设计
一、插件介绍
Unity插件-Mirror使用方法(一)Mirror介绍-CSDN博客
二、主要组件
Unity插件-Mirror使用方法(二)组件介绍-CSDN博客
Network Manager
Unity插件-Mirror使用方法(三)组件介绍(Network Manager)-CSDN博客
Network Manager HUD
Unity插件-Mirror使用方法(四)组件介绍(Network Manager HUD)-CSDN博客
Network Identity
Unity插件-Mirror使用方法(五)组件介绍(Network Identity)-CSDN博客
Network Transform
Unity插件-Mirror使用方法(六)组件介绍(Network Transform)-CSDN博客
Network Animator
Unity插件-Mirror使用方法(七)组件介绍(Network Animator)-CSDN博客
Network Behaviour
Unity插件-Mirror使用方法(八)组件介绍(Network Behaviour)-CSDN博客
Network Start Position
Unity插件-Mirror使用方法(九)组件介绍(Network Start Position)-CSDN博客
Network Room Manager
Unity插件-Mirror使用方法(十)组件介绍(Network Room Manager)-CSDN博客
三、Network Room Player
1、组件介绍
Network Room Player 是 Unity Mirror 中用于管理房间内玩家状态的核心组件,与 NetworkRoomManager
配合使用,负责同步玩家在房间中的信息(如准备状态、角色选择、队伍分配等)。每个加入房间的玩家都会生成一个 NetworkRoomPlayer
实例,作为其在大厅场景中的代表,直至游戏开始。
该组件用于在房间场景中为每个玩家存储状态信息。使用该组件时,需要编写允许玩家标记准备状态的脚本,通过设置ReadyToBegin属性来实现。
技术规范:
- 带有Network Room Player组件的游戏对象必须同时包含Network Identity组件
- 当创建Network Room Player组件时,若对象未包含Network Identity组件,Unity会自动创建
2、核心功能
-
玩家状态同步
-
通过
[SyncVar]
同步玩家名称、准备状态、队伍、角色皮肤等属性。 -
自动更新所有客户端的房间玩家列表,确保状态一致。
-
-
UI交互控制
-
处理本地玩家的准备/取消准备、角色选择等操作。
-
通过
[Command]
向服务器发送状态变更请求,并在服务器验证后同步。
-
-
生命周期管理
-
提供玩家加入、离开房间的回调方法(如
OnClientEnterRoom
、OnClientExitRoom
)。 -
在游戏开始时,将
RoomPlayer
替换为实际的游戏角色(GamePlayer
)。
-
-
权限管理
-
区分本地玩家与远程玩家,控制UI交互权限(如仅本地玩家可点击准备按钮)。
-
3、关键属性与配置
属性 | 说明 |
---|---|
显示房间GUI界面(Show Room GUI) | 启用开发者界面用于房间内玩家状态显示(默认开启,建议正式发布时禁用) |
准备状态(Ready To Begin) | 诊断性指示器,标识玩家是否已准备就绪 |
玩家索引(Index) | 诊断性标识,显示玩家序号(如玩家1、玩家2等) |
网络同步间隔(Network Sync Interval) | 控制玩家状态数据从客户端同步到服务器的频率(单位:秒) |
4、基础使用步骤
步骤1:创建房间玩家预制体
-
创建UI预制体(如
RoomPlayerPrefab
),包含玩家名称文本、准备状态图标、准备按钮等元素。 -
为预制体添加
NetworkRoomPlayer
组件(或继承自该组件的自定义脚本)。 -
将该预制体拖入
NetworkRoomManager
的 Room Player Prefab 属性。
步骤2:同步玩家状态
using UnityEngine;
using Mirror;
public class RoomPlayer : NetworkRoomPlayer {
[SyncVar(hook = nameof(UpdateNameDisplay))]
public string playerName = "Player";
[SyncVar(hook = nameof(UpdateReadyUI))]
public bool isReady;
public Text nameText;
public GameObject readyIcon;
// 本地玩家点击准备按钮
public void OnReadyButtonClick() {
CmdToggleReady();
}
[Command]
private void CmdToggleReady() {
isReady = !isReady;
}
// 客户端同步准备状态
private void UpdateReadyUI(bool oldValue, bool newValue) {
readyIcon.SetActive(newValue);
}
// 客户端同步名称
private void UpdateNameDisplay(string oldValue, string newValue) {
nameText.text = newValue;
}
// 服务器初始化时设置名称
public override void OnStartServer() {
playerName = "Player_" + Random.Range(100, 999);
}
}
步骤3:房间玩家生命周期回调
方法说明
客户端同步变量钩子方法
public virtual void IndexChanged(int oldIndex, int newIndex) { } // 当玩家索引变更时触发
public virtual void ReadyStateChanged(bool oldReadyState, bool newReadyState) { } // 当准备状态变更时触发
客户端虚拟方法
public virtual void OnClientEnterRoom() { } // 客户端进入房间时调用
public virtual void OnClientExitRoom() { } // 客户端退出房间时调用
[Obsolete("OnClientReady方法已弃用,请改用ReadyStateChanged同步变量钩子")]
public virtual void OnClientReady(bool readyState) {} // 准备状态变更回调(已废弃)
public class CustomRoomPlayer : NetworkRoomPlayer {
// 客户端进入房间时调用
public override void OnClientEnterRoom() {
Debug.Log($"{playerName} 进入房间");
}
// 客户端离开房间时调用
public override void OnClientExitRoom() {
Debug.Log($"{playerName} 离开房间");
}
// 本地玩家获得控制权时调用
public override void OnStartLocalPlayer() {
GetComponent<Button>().interactable = true; // 启用本地操作按钮
}
}
5、高级功能与场景
1. 角色选择系统
public class RoomPlayer : NetworkRoomPlayer {
[SyncVar(hook = nameof(UpdateCharacterIcon))]
public int selectedCharacterId;
public Image characterIcon;
public void OnCharacterButtonClick(int characterId) {
CmdSelectCharacter(characterId);
}
[Command]
private void CmdSelectCharacter(int characterId) {
selectedCharacterId = characterId;
}
private void UpdateCharacterIcon(int oldId, int newId) {
characterIcon.sprite = characterDatabase.GetIcon(newId);
}
}
2. 房主权限管理
public class RoomPlayer : NetworkRoomPlayer {
[SyncVar(hook = nameof(UpdateLeaderUI))]
public bool isLeader;
public GameObject kickButton;
private void UpdateLeaderUI(bool oldValue, bool newValue) {
kickButton.SetActive(newValue); // 仅房主显示踢人按钮
}
public void OnKickButtonClick(int targetPlayerId) {
if (isLeader) {
CmdKickPlayer(targetPlayerId);
}
}
[Command]
private void CmdKickPlayer(int targetPlayerId) {
// 根据ID找到对应连接并断开
foreach (var conn in NetworkServer.connections.Values) {
if (conn.identity.GetComponent<RoomPlayer>().Index == targetPlayerId) {
conn.Disconnect();
break;
}
}
}
}
3. 跨场景数据传递
public class RoomPlayer : NetworkRoomPlayer {
[SyncVar]
public int playerLevel;
[SyncVar]
public Color playerColor;
// 游戏开始时将数据传递给GamePlayer
public override void OnRoomServerSceneLoadedForPlayer(NetworkConnection conn, GameObject roomPlayer, GameObject gamePlayer) {
gamePlayer.GetComponent<GamePlayer>().playerLevel = roomPlayer.GetComponent<RoomPlayer>().playerLevel;
gamePlayer.GetComponent<GamePlayer>().playerColor = roomPlayer.GetComponent<RoomPlayer>().playerColor;
}
}
6、常见问题与解决
问题 | 解决方案 |
---|---|
准备状态不同步 | 确保使用 [Command] 修改 SyncVar ,且服务器逻辑正确。 |
玩家列表不更新 | 检查 NetworkRoomManager 的 roomSlots 是否包含所有玩家实例。 |
本地玩家UI未激活 | 在 OnStartLocalPlayer 中启用交互组件(如按钮)。 |
游戏开始时玩家未生成 | 在 NetworkRoomManager 的 OnRoomServerSceneChanged 中调用替换玩家方法。 |
7、最佳实践
UI与逻辑分离
- 使用
SyncVar
的hook
更新UI,避免直接在Command/RPC中操作UI元素。
输入验证
- 所有客户端发起的操作需在服务器验证(如检查玩家是否为房主)。
性能优化
- 减少高频同步数据(如实时位置),仅在状态变化时同步。
扩展性设计
- 将房间玩家数据与游戏玩家数据分离,通过场景切换传递必要信息。