Unity集成ZEGO实时语音SDK实现多人状态实时同步

多人状态实时同步功能简介

多人状态实时同步功能提供有序、高频、低延时、大规模的状态同步服务,帮助开发者快速实现虚拟玩法中玩家的位置、动作、形象等实时信息同步能力,同时单场景中支持 1 万个用户同时在线。

在大型虚拟世界中,用户一般不需要感知较远的场景或远端用户,ZEGO 提供 AOI(Area Of Interest)能力,用于减免获取用户可见范围外的信息,极大减少客户流量成本、用户端流量及性能消耗。

Unity集成ZEGO实时语音SDK实现多人状态实时同步

概念解释

  • 场景:用户需要先登录场景,进入同一个场景的用户才可以进行状态信息的同步。
  • AOI(Area of interest)范围:用户感兴趣区域的正方形大小,在虚拟场景中一般为用户的可见范围,该范围实时跟随用户的位置,仅会同步 AOI 范围内远端的用户信息。

应用场景

  • 虚拟办公、虚拟会展、虚拟社交、虚拟 KTV 等元宇宙场景。
  • 需要超高频、低延时、大规模同步信息或控制指令的通用场景。

前提条件

在实现状态同步前,请确保:

  • 已联系 ZEGO 技术支持进行特殊编包并开通状态同步服务。
  • 已在项目中集成 ZEGO Express SDK。
  • 已在 ZEGO 控制台 创建项目,并申请有效的 AppID 和 AppSign,详情请参考 控制台 – 项目管理

多人状态实时同步实现流程

1 创建引擎

调用 CreateEngine 接口,将申请到到 AppID 和 AppSign 传入参数 “appID” 和 “appSign”,创建引擎单例对象。引擎当前只支持同时创建一个实例,超出后将返回 null。

/** 定义 SDK 引擎对象 */
ZegoExpressEngine engine;

ZegoEngineProfile profile = new ZegoEngineProfile();
/** 请通过官网注册获取,格式为 123456789 */
profile.appID = appID;
/** 64个字符,请通过官网注册获取,格式为"0123456789012345678901234567890123456789012345678901234567890123" */
profile.appSign = appSign;
/** 通用场景接入 */
profile.scenario = ZegoScenario.Default;
/** 创建引擎 */
engine = ZegoExpressEngine.CreateEngine(profile);

2 创建范围场景模块

调用 CreateRangeScene 接口创建范围场景实例,当前只支持同时创建一个实例,超出后将返回 null。

/** 定义范围场景对象 */
ZegoRangeScene rangeScene;

/** 创建范围场景 */
rangeScene = engine.CreateRangeScene();

3 监听范围场景事件回调

根据需要设置范围场景事件委托,用于监听范围场景状态、登录状态、进出 AOI 通知等。通过设置范围场景物品管理类事件委托,用于监听物品进入离开 AOI 范围、物品绑定状态变更、物品状态和命令更新事件。

/** 范围场景事件回调 */
public void OnSceneStateUpdate(ZegoRangeScene rangeScene, ZegoSceneState state, int errorCode) {

}

public void OnEnterView(ZegoRangeScene rangeScene, ZegoUser user, ZegoPosition position) {

}

public void OnLeaveView(ZegoRangeScene rangeScene, string userID) {

}

public void OnUserStatusUpdate(ZegoRangeScene rangeScene, string userID, ZegoPosition position, uint channel, byte[] status) {

}

public void OnUserCommandUpdate(ZegoRangeScene rangeScene, string userID, ZegoPosition position, uint channel, byte[] command) {

}

public void OnCustomCommandUpdate(ZegoRangeScene rangeScene, byte[] command) {

}

/** 范围场景流管理事件回调 */
public void OnUserStreamStateUpdate(ZegoRangeScene rangeScene, string userID, string streamID, ZegoStreamState state) {

}

public void OnUserMicUpdate(ZegoRangeScene rangeScene, string userID, ZegoDeviceState state) {

}

public void OnUserCameraUpdate(ZegoRangeScene rangeScene, string userID, ZegoDeviceState state) {

}

public void OnUserSpeakerUpdate(ZegoRangeScene rangeScene, string userID, ZegoDeviceState state) {

}

// 设置委托
rangeScene.onSceneStateUpdate = OnSceneStateUpdate;
rangeScene.onEnterView = OnEnterView;
rangeScene.onLeaveView = OnLeaveView;
rangeScene.onUserStatusUpdate = OnUserStatusUpdate;
rangeScene.onUserCommandUpdate = OnUserCommandUpdate;
rangeScene.onCustomCommandUpdate=OnCustomCommandUpdate;
rangeScene.GetRangeSceneStream().onUserStreamStateUpdate = OnUserStreamStateUpdate;
rangeScene.GetRangeSceneStream().onUserMicUpdate = OnUserMicUpdate;
rangeScene.GetRangeSceneStream().onUserCameraUpdate = OnUserCameraUpdate;
rangeScene.GetRangeSceneStream().onUserSpeakerUpdate = OnUserSpeakerUpdate;

4 登录场景

调用 LoginScene 接口,传入场景参数:sceneID、user、position、broadcastMode,即可登录场景。

/** 登录场景参数 */
ZegoSceneParam param = new ZegoSceneParam();
/** 创建用户 */
ZegoUser user = new ZegoUser(userID);
/** 设置用户的场景坐标、运动朝向、摄像机朝向 */
ZegoPosition position = new ZegoPosition()
position.coordinate.z = self_pos[0];
position.coordinate.x = self_pos[1];
position.coordinate.y = self_pos[2];
position.motionOrientation.axisForward.z = axis_forward[0];
position.motionOrientation.axisForward.x = axis_forward[1];
position.motionOrientation.axisForward.y = axis_forward[2];
position.motionOrientation.axisRight.z = axis_right[0];
position.motionOrientation.axisRight.x = axis_right[1];
position.motionOrientation.axisRight.y = axis_right[2];
position.motionOrientation.axisUp.z = axis_top[0];
position.motionOrientation.axisUp.x = axis_top[1];
position.motionOrientation.axisUp.y = axis_top[2];
position.cameraOrientation.axisForward = axisForward;
position.cameraOrientation.axisRight = axisRight;
position.cameraOrientation.axisUp = axisUp;
/** 设置场景 ID */
param.sceneID = sceneID;
/** (可选)配置模版 ID */
param.templateID = template_id;
param.user = user;
param.position = position;
/** 设置用户登录场景的广播模式 */
param.broadcastMode = ZegoBroadcastMode.All;
rangeScene.LoginScene(sceneParam, (int errorCode, ZegoSceneConfig config) => {

});

5 同步状态

通过 UpdateUserStatus、UpdateUserCommand 接口更新用户状态及用户命令。通过 OnUserStatusUpdate、OnUserCommandUpdate 回调接收 AOI 范围内的远端用户位置、命令等状态信息。

用户状态(status,S)是全量更新,用户命令是增量更新(command,C),用户状态可以由前一个用户状态经过一系列用户命令计算得出。
用户更新状态的模型应是 Si->Ci->Ci+1->Ci+2->…Ci+j->S(i+1)->C(i+1)+1->C(i+1)+2->…C(i+1)+k->S(i+2)->C(i+2)->…
状态同步服务将保证 Si、Si+1 两个全量状态(status)之间的增量更新(command)有序到达。
/** 设置用户的场景坐标、运动朝向、摄像机朝向 */
ZegoPosition position = new ZegoPosition();
position.coordinate.z = self_pos[0];
position.coordinate.x = self_pos[1];
position.coordinate.y = self_pos[2];
position.motionOrientation.axisForward.z = axis_forward[0];
position.motionOrientation.axisForward.x = axis_forward[1];
position.motionOrientation.axisForward.y = axis_forward[2];
position.motionOrientation.axisRight.z = axis_right[0];
position.motionOrientation.axisRight.x = axis_right[1];
position.motionOrientation.axisRight.y = axis_right[2];
position.motionOrientation.axisUp.z = axis_top[0];
position.motionOrientation.axisUp.x = axis_top[1];
position.motionOrientation.axisUp.y = axis_top[2];
position.cameraOrientation.axisForward = axisForward;
position.cameraOrientation.axisRight = axisRight;
position.cameraOrientation.axisUp = axisUp;

/** 更新用户状态 */
byte[] status = new byte[10];
int errorCode = rangeScene.UpdateUserStatus(position, 0, status);

/** 更新用户命令 */
byte[] command = new byte[10];
int errorCode = rangeScene.UpdateUserCommand(position, 0, command);

6 (可选)获取场景内用户数、获取 AOI 范围内用户列表

可以根据需要调用 GetUserCount、GetUserListInView 接口获取场景内用户数、AOI 范围内用户列表。

/** 获取场景内用户数 */
rangeScene.GetUserCount((int errorCode, uint count) =>{

});

/** 获取 AOI 范围内用户列表 */
rangeScene.GetUserListInView((int errorCode, List<string> userList) =>{

});

7 退出场景

调用 LogoutScene 接口退出场景。

/** 退出场景 */
rangeScene.LogoutScene((int errorCode) => {

});

8 销毁范围场景模块

当不再使用范围场景模块时,可以调用 DestroyRangeScene 接口销毁范围场景模块。

engine.DestroyRangeScene(rangeScene);

9 销毁引擎

当不再使用 ZEGO Express SDK 时,可以调用 DestroyEngine 销毁引擎。

ZegoExpressEngine.DestroyEngine();

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/yinshipin/9411.html

(1)

相关推荐

发表回复

登录后才能评论