API 文档 / v1.0.2
v1.0.2

API 文档

公开 API 按模块列出。接入说明见 SDK 开发文档。

概述

模块类型
框架FrameworkEntry、FrameworkBootstrap、ServiceLocator、IEventBus、ISceneService、ITimerService、ITimeService、ICoroutineRunner、IResourceService、ILogService、BootSystem
管控ContentStateSync、CalibrationHandler、IPDAutoCalibrator
大空间ExperienceAreaHandler、DetectingSystem、ExperienceAreaSafetyPresenter、ExperienceAreaItem
内容Enums、ExperienceAreaIdAttribute、ContentSceneSearcher、ContentSceneDirectorSample、RoomContentSceneFlow、ContentProgressReporter
网络RoomNetClient、RoomMgr、EventBroadcastHandler、CustomMessageHandler、NetworkedObject、ObjectSyncHandler、MemberHandler、TransformHandler、ContentSyncHandler、AnimationSyncHandler、TimeSyncHandler、AvatarMgr、AvatarMono
交互HandGesturesMgr、HandGestureHold、CustomGazeInteractor

框架

FrameworkEntry

API说明
void FrameworkEntry.Awake()入口自动调 FrameworkBootstrap.InitFramework();Inspector nextScene 可空

FrameworkBootstrap

API说明
void FrameworkBootstrap.InitFramework()注册基础服务(Entry 会自动调)

ServiceLocator

API说明
void ServiceLocator.Register<T>(T service)注册服务
T ServiceLocator.Get<T>()取服务,未注册抛异常
bool ServiceLocator.TryGet<T>(out T service)取服务,未注册不抛

IEventBus

API说明
void IEventBus.Subscribe(int id, Action<GameEventArg> listener)订阅本地事件
void IEventBus.Unsubscribe(int id, Action<GameEventArg> listener)取消订阅,须同一委托
void IEventBus.Publish(int id, Action<GameEventArg> setupArgs = null)发布
GameEventArg IEventBus.GetArgs(int id)取事件参数对象

ISceneService

API说明
void ISceneService.LoadSceneAsync(string sceneName, LoadSceneMode mode = Single, Action<float> onProgress = null, Action onCompleted = null)mode:Single 卸当前 / Additive 叠加;onProgress 0~1
void ISceneService.UnloadSceneAsync(string sceneName, Action<float> onProgress = null, Action onCompleted = null)异步卸载

ITimerService / ITimerHandle

API说明
ITimerHandle ITimerService.Wait(float seconds, Action callback, bool useUnscaledTime = false)延迟回调
ITimerHandle ITimerService.WaitFrame(int frameCount, Action callback)延迟 N 帧
ITimerHandle ITimerService.Repeat(float intervalSeconds, Action callback, int repeatCount = -1, bool immediate = false, bool useUnscaledTime = false)重复;repeatCount < 0 无限
ITimerHandle ITimerService.RepeatFrame(int intervalFrames, Action callback, int repeatCount = -1, bool immediate = false)按帧重复
bool ITimerHandle.IsDone { get; }是否已结束
void ITimerHandle.Cancel()取消定时器

ITimeService

API说明
float ITimeService.DeltaTime { get; }缩放后 delta
float ITimeService.UnscaledDeltaTime { get; }未缩放 delta
float ITimeService.Time { get; }缩放后时间
float ITimeService.UnscaledTime { get; }未缩放时间
float ITimeService.TimeScale { get; set; }时间缩放

ICoroutineRunner

API说明
Coroutine ICoroutineRunner.Run(IEnumerator routine)开协程
void ICoroutineRunner.Stop(Coroutine coroutine)停一个
void ICoroutineRunner.StopAll()停全部

IResourceService

API说明
T IResourceService.LoadAsset<T>(string location)同步加载
void IResourceService.LoadAssetAsync<T>(string location, Action<T> onCompleted)异步加载
void IResourceService.UnloadAsset(UnityEngine.Object asset)卸载资源

ILogService

API说明
void ILogService.Log(string context, string message)日志
void ILogService.Warning(string context, string message)警告
void ILogService.Error(string context, string message)错误

BootSystem

API说明
string BootSystem.DeviceSn { get; }设备 SN
void BootSystem.SetDeviceSn(string sn)设置设备 SN
ContentMode BootSystem.ContentMode { get; }LargeSpace / Origin
RunningMode BootSystem.RunningMode { get; }运行模式
BootConfigRoot BootSystem.Root { get; }已解析的 boot 配置
string BootSystem.EditorMapConfigUrl { get; }Editor 地图 JSON 路径
string BootSystem.ResolveBootConfigPath()当前 boot 文件路径
bool BootSystem.StoragePermissionReady { get; }存储权限是否就绪
bool BootSystem.BindToBServer { get; }是否已绑定管控服务
void BootSystem.RegisterFocus(UnityAction<bool> onFocus)环境纹理检测焦点回调
void BootSystem.UnRegisterFocus(UnityAction<bool> onFocus)取消焦点回调
int BootSystem.GotoEnvironmentTextureCheck()进入环境纹理检测
if (!ServiceLocator.TryGet<ISceneService>(out var scenes)) return;
scenes.LoadSceneAsync("Level_A", LoadSceneMode.Additive, onCompleted: () => { });

if (!ServiceLocator.TryGet<ITimerService>(out var timer)) return;
var handle = timer.Wait(30f, () => { /* 超时 */ });
handle.Cancel();

if (!ServiceLocator.TryGet<IEventBus>(out var bus)) return;
bus.Subscribe(100, _ => { });
bus.Publish(100);

string sn = BootSystem.Instance.DeviceSn;

管控

ContentStateSync

API说明
bool autoSync勾选:校准后自动同步,并本地置 Running。等管控开播须取消,自己调 StartSync
ContentStatus ContentStateSync.ContentStatus { get; }当前内容状态
RoomData ContentStateSync.Room { get; }房间分配数据
bool ContentStateSync.IsLateJoiner { get; }进房时房间已 Running(中途加入)
void ContentStateSync.StartSync()开始握手 / 上报 / 连房间;不是开播。autoSync 未勾选时须内容自己调
void ContentStateSync.StopSync()停止上报
void ContentStateSync.SetContentProgress(int progress, string progressNode)只写进度 0~100,不上报
void ContentStateSync.SetContentProgressAndReport(int progress, string progressNode)写进度并立即上报
void ContentStateSync.NotifyExperienceStarted()本地 Ready → Running(无管控开播时)
void ContentStateSync.NotifyAgreementFinished()打开体验计时:已 Running 且调过它才开始计时;不调时长为 0
void ContentStateSync.NotifyCalibrationFinished()校准完成 → Ready
void ContentStateSync.NotifyGameFinished(JsonData payload = null)上报结束;payload 默认可空
bool ContentStateSync.TryGetPlayerName(string sn, out string nickName)按设备 SN 取昵称

ContentStatus

值说明
Unknown = -1未知
Connected = 0已握手
Calibration = 100校准中
Ready = 200就绪(可接收开播)
Running = 300已开播
Shutdown = 400结束

CalibrationHandler

API说明
CalibrationState CalibrationHandler.CalibrationState { get; }UnCalibration / Calibration / CalibrationEnd

IPDAutoCalibrator

API说明
void IPDAutoCalibrator.EnableIPDAdjustment()开启音量键 IPD 调节
contentStateSync.StartSync();
director.GoTo(ContentSceneSearcher.佩戴区);

if (!contentStateSync.IsLateJoiner)
    yield return new WaitUntil(() =>
        contentStateSync.ContentStatus == ContentStatus.Running);

contentStateSync.NotifyAgreementFinished();
director.GoTo(ContentSceneSearcher.内容1);

大空间

ExperienceAreaHandler

API说明
void ExperienceAreaHandler.LoadBoundaryPlace()按 Boot 实例化体验区
bool ExperienceAreaHandler.SwitchExperienceArea(string areaId, bool deactivateOthers = true, bool alignContentRoot = true)切换当前区
bool ExperienceAreaHandler.SwitchToNextExperienceArea(bool loop = false, bool alignContentRoot = true)按顺序切下一区
bool ExperienceAreaHandler.ShowExperienceAreaPreview(string areaId)预览指定区边界,不改当前区
bool ExperienceAreaHandler.ShowNextExperienceArea(bool loop = false)预览下一区
void ExperienceAreaHandler.ClearExperienceAreaPreview()清除预览
void ExperienceAreaHandler.SetContentRoot(GameObject root)指定内容根
void ExperienceAreaHandler.AlignContentRootToActiveArea()把根对齐到当前区
string ExperienceAreaHandler.GetNextExperienceAreaId(bool loop = false)下一区 id,没有则 null
ExperienceAreaItem ExperienceAreaHandler.GetArea(string id)取区实例,没有则 null
ExperienceAreaItem ExperienceAreaHandler.ExperienceAreaItem { get; }当前体验区实例
ExperienceAreaItem ExperienceAreaHandler.PreviewArea { get; }当前预览区实例
bool ExperienceAreaHandler.IsBoundaryReady { get; }场地是否就绪
string ExperienceAreaHandler.ActiveAreaId { get; }当前体验区 id
string ExperienceAreaHandler.PreviewAreaId { get; }当前预览区 id
bool ExperienceAreaHandler.CameraMaskLocked { get; }相机 mask 是否锁定
void ExperienceAreaHandler.LockCameraMask(bool locked)锁定后 Safety 不再改 mask
void ExperienceAreaHandler.SetCameraLayerMask(bool boundaryMask)true 出区 mask,false 默认 mask
void ExperienceAreaHandler.SetCameraLayerMask(LayerMask layerMask)直接指定 mask
event Action<ExperienceAreaChange> ExperienceAreaHandler.OnAreaChanged切区;FromId / ToId
event Action<ExperienceAreaChange> ExperienceAreaHandler.OnPreviewChanged预览变化
var h = GetComponent<ExperienceAreaHandler>();
h.LoadBoundaryPlace();
h.SetContentRoot(root);
bool ok = h.SwitchExperienceArea("area_01");
h.ShowExperienceAreaPreview("area_02");
h.OnAreaChanged += e => { /* e.FromId, e.ToId */ };

DetectingSystem

API说明
void DetectingSystem.EnableDetecting()开始检测
void DetectingSystem.DisableDetecting()停止检测并清空当前区
void DetectingSystem.RegisterHeadDetecting(UnityAction<RunningContentData> callback)头部位姿检测回调
void DetectingSystem.UnRegisterHeadDetecting(UnityAction<RunningContentData> callback)取消,须同一委托
bool DetectingSystem.IsInObstacle()是否在障碍内
List<ExperienceAreaItem> DetectingSystem.ContentArea { get; }头部当前所在内容区
List<GameObject> DetectingSystem.HexRoad { get; }当前 Hex 通道
List<GameObject> DetectingSystem.Obstacles { get; }当前障碍

RunningContentData

API说明
int RunningContentData.isOutContentArea1 出区,0 在区内
string RunningContentData.currentAreas当前区名,逗号拼接
DetectingSystem.Instance.EnableDetecting();
DetectingSystem.Instance.RegisterHeadDetecting(data => {
    bool outArea = data.isOutContentArea == 1;
    string areas = data.currentAreas;
});
bool inObstacle = DetectingSystem.Instance.IsInObstacle();

ExperienceAreaSafetyPresenter

API说明
bool ExperienceAreaSafetyPresenter.CameraMaskLocked { get; }相机 mask 是否锁定
void ExperienceAreaSafetyPresenter.LockCameraMask(bool locked)锁定后不再自动改 mask
void ExperienceAreaSafetyPresenter.SetCameraLayerMask(bool boundaryMask)true 出区 mask,false 默认 mask
void ExperienceAreaSafetyPresenter.SetCameraLayerMask(LayerMask layerMask)直接指定 mask

ExperienceAreaItem

API说明
bool ExperienceAreaItem.IsOutAreaVisible { get; }出区线是否显示
void ExperienceAreaItem.SetOutAreaVisible(bool show)显示出区线
void ExperienceAreaItem.SetGuideVisible(bool show)显示引导
void ExperienceAreaItem.SetObstacleVisualInObstacle(bool inObstacle)障碍内视觉
PlaceItem ExperienceAreaItem.PlaceItem { get; }该区 place 数据
var area = h.GetArea(h.ActiveAreaId);
area.SetOutAreaVisible(true);
area.SetGuideVisible(true);
h.SetCameraLayerMask(true);
h.LockCameraMask(true);

边界标记

类型说明
ExperienceHexRoadMarkerHex 通道检测
ExperienceObstacleMarker障碍检测
ExperienceNearAreaLineMarker近区线
ExperienceOutAreaLineMarker出区线
ExperienceObstacleAreaMarker障碍区视觉
ExperienceBoundaryVisualMarker子视觉;Kind:Boundary / Arrow / GuideLine

内容

Enums

API说明
string Enums.GetDescByEnum(this Enum value)读 [Description],可作场景名
string Enums.GetAreaIdByEnum(this Enum value)读 [ExperienceAreaId];无标注返回 ""
T Enums.GetAttributeOfType<T>(this Enum enumVal)读任意特性
T Enums.GetValueByIndex<T>(int index)按下标取枚举值
int Enums.GetIndexByValue<T>(T enumVal)取枚举下标
T Enums.GetEnumByDescription<T>(string description)按 Description 反查枚举

ExperienceAreaIdAttribute

API说明
ExperienceAreaIdAttribute(string areaId)标在枚举字段上,值为 Boot placeItems.id
string ExperienceAreaIdAttribute.AreaId { get; }体验区 id
public enum MyStep {
    [Description("Level_Wear")]
    [ExperienceAreaId("area_01")]
    Wear,
}

string scene = MyStep.Wear.GetDescByEnum();
string area  = MyStep.Wear.GetAreaIdByEnum();

ContentSceneSearcher / ContentSceneStepMap

API说明
ContentSceneSearcher.佩戴区 / 内容1 / 内容2 / 归还区示例步骤;Description=场景名,ExperienceAreaId=areaId
string ContentSceneStepMap.GetSceneName(ContentSceneSearcher step)场景名;空字符串表示本步不加载场景
string ContentSceneStepMap.GetAreaId(ContentSceneSearcher step)体验区 id
string scene = ContentSceneStepMap.GetSceneName(ContentSceneSearcher.内容1); // Level_B
string area  = ContentSceneStepMap.GetAreaId(ContentSceneSearcher.内容1);    // area_02

ContentSceneDirectorSample

API说明
void ContentSceneDirectorSample.GoTo(ContentSceneSearcher step, bool forceReload = false)进入步骤:有场景则加载,再切体验区;无场景只切区
void ContentSceneDirectorSample.NextContent()下一步
void ContentSceneDirectorSample.PrevContent()上一步
void ContentSceneDirectorSample.SwitchToNextExperienceArea()切下一体验区
void ContentSceneDirectorSample.ShowNextExperienceAreaPreview()预览下一区
void ContentSceneDirectorSample.ClearExperienceAreaPreview()清除预览
void ContentSceneDirectorSample.StartAutoCycleExperienceAreas()自动循环步骤(联调用)
void ContentSceneDirectorSample.StopAutoCycleExperienceAreas()停止自动循环
ContentSceneSearcher ContentSceneDirectorSample.CurrentStep { get; }当前步骤
string ContentSceneDirectorSample.LoadedContentScene { get; }已加载的内容场景名
bool ContentSceneDirectorSample.IsBusy { get; }是否正在切步
event Action<ContentSceneSearcher> ContentSceneDirectorSample.OnContentStepChanged步骤变化
var director = GetComponent<ContentSceneDirectorSample>();
director.GoTo(ContentSceneSearcher.内容1);
director.NextContent();
director.OnContentStepChanged += step => { };

RoomContentSceneFlow

API说明
void RoomContentSceneFlow.ClientRequestNextContent(ContentSceneSearcher step)请求切内容步骤
void RoomContentSceneFlow.ClientRequestNextExperienceArea(string areaId)请求切体验区
void RoomContentSceneFlow.SetSceneStep(ContentSceneSearcher step, bool notify = true)写入当前步骤
void RoomContentSceneFlow.SetExperienceAreaStep(string areaId, bool notify = true)写入当前体验区
ContentSceneSearcher RoomContentSceneFlow.SceneStep { get; }当前步骤
string RoomContentSceneFlow.ExperienceAreaId { get; }当前体验区 id
event Action<ContentSceneSearcher> RoomContentSceneFlow.OnSceneStepChanged步骤确认
event Action<string> RoomContentSceneFlow.OnExperienceAreaStepChanged体验区确认
var flow = RoomContentSceneFlow.Instance;
flow.OnSceneStepChanged += step => director.GoTo(step);
flow.ClientRequestNextContent(ContentSceneSearcher.内容1);
flow.ClientRequestNextExperienceArea("area_02");

ContentProgressReporter

API说明
void ContentProgressReporter.OnContentStepChanged(ContentSceneSearcher step)切步后重算本段进度
void ContentProgressReporter.OnExperienceAreaChanged(string areaId)更新 progressNode
void ContentProgressReporter.ResetProgress()进度归零
void ContentProgressReporter.SetSnapSegmentProgress(bool enabled)快进:离段记满,段内不按时长涨
int ContentProgressReporter.GlobalProgressPct { get; }整局 0~100
bool ContentProgressReporter.GameFinished { get; }是否已到 100% 并上报结束
reporter.OnContentStepChanged(ContentSceneSearcher.内容1);
int pct = reporter.GlobalProgressPct;
reporter.ResetProgress();

网络

RoomNetClient

API说明
void RoomNetClient.Configure(string ip, int port, string roomKey = null)写入地址,不自动连
void RoomNetClient.Connect()发起连接
void RoomNetClient.Disconnect()断开
RoomNetStatus RoomNetClient.ConnectStatus { get; }Initialize / Connecting / Connected / Disconnected / Stopped
bool RoomNetClient.IsConnected { get; }是否已连上
bool RoomNetClient.IsServerConfigured { get; }IP 与端口是否已配
int RoomNetClient.LocalPlayerId { get; }本端玩家 Id,未就绪 -1
RoomMember RoomNetClient.Self { get; }本端成员
string RoomNetClient.ServerIp { get; }房间服务 IP
int RoomNetClient.ServerPort { get; }房间服务端口
event Action RoomNetClient.OnRoomConnected连上
event Action RoomNetClient.OnRoomDisconnected断开
RoomNetClient.Instance.Configure("192.168.x.x", 11001);
RoomNetClient.Instance.Connect();
RoomNetClient.Instance.OnRoomConnected += () => { };
int self = RoomNetClient.Instance.LocalPlayerId;

RoomMgr

API说明
RoomNetClient RoomMgr.RoomNetClient { get; }房间连接
EventBroadcastHandler RoomMgr.EventBroadcastHandler { get; }房间事件广播
MemberHandler RoomMgr.MemberHandler { get; }成员列表
TransformHandler RoomMgr.TransformHandler { get; }头手位姿
ObjectSyncHandler RoomMgr.ObjectSyncHandler { get; }物体同步
void RoomMgr.RegisterObject(NetworkedObject networkedObject)注册场景物体
void RoomMgr.RegisterPrefab(string prefabName, GameObject prefab)注册生成用预制体
uint RoomMgr.SpawnObject(string goName, Vector3 pos, Quaternion rot, Vector3 scale, string customData)goName 对应已注册预制体名
void RoomMgr.RequestOwnership(uint id, bool force)按 objectId 申请所有权
void RoomMgr.ReleaseOwnership(uint id)释放所有权
void RoomMgr.CleanupRoomState()清房间状态(断线时会调)
event Action RoomMgr.OnRoomStateCleaned房间状态已清理

EventBroadcastHandler

API说明
void EventBroadcastHandler.RegisterEvent(ushort eventId, UnityAction<int, byte[]> listener)注册;senderId 为触发方玩家 Id,payload 可空
void EventBroadcastHandler.RegisterStringEvent(ushort eventId, UnityAction<int, string> listener)字符串 payload
void EventBroadcastHandler.RegisterJsonEvent<T>(ushort eventId, UnityAction<int, T> listener)JSON payload
void EventBroadcastHandler.RegisterSimpleEvent(ushort eventId, UnityAction<int> listener)无 payload
void EventBroadcastHandler.TriggerEvent(ushort eventId, byte[] payload = null)发送字节
void EventBroadcastHandler.TriggerEventString(ushort eventId, string data)发送字符串
void EventBroadcastHandler.TriggerEventJson<T>(ushort eventId, T obj)发送 JSON
void EventBroadcastHandler.TriggerEventSimple(ushort eventId)无 payload 发送
void EventBroadcastHandler.UnregisterEvent(ushort eventId, UnityAction<int, byte[]> listener)取消注册
void EventBroadcastHandler.RegisterGlobalListener(UnityAction<int, ushort, byte[]> listener)监听全部 eventId
void EventBroadcastHandler.UnregisterGlobalListener(UnityAction<int, ushort, byte[]> listener)取消全局监听
bool EventBroadcastHandler.IsEventRegistered(ushort eventId)该 eventId 是否已注册
event Action<int, ushort, byte[]> EventBroadcastHandler.OnEventReceived收到任意事件

自定义 eventId 服务器只转发。101 / 104:同等人数、相同 payload 后回 201 / 204。

var eb = RoomMgr.Instance.EventBroadcastHandler;
eb.RegisterEvent(1001, (senderId, payload) => {
    bool fromSelf = senderId == RoomNetClient.Instance.LocalPlayerId;
});
eb.TriggerEvent(1001, myBytes);
eb.TriggerEventString(1002, "hello");
eb.TriggerEventJson(1003, dto);
eb.TriggerEventSimple(1004);

CustomMessageHandler

API说明
void CustomMessageHandler.RegisterChannel(ushort channelId, UnityAction<int, byte[]> handler)注册频道
void CustomMessageHandler.UnregisterChannel(ushort channelId)取消频道
bool CustomMessageHandler.IsChannelRegistered(ushort channelId)频道是否已注册
void CustomMessageHandler.SendReliable(ushort channelId, byte[] data)可靠发送
void CustomMessageHandler.SendUnreliable(ushort channelId, byte[] data)不可靠发送
void CustomMessageHandler.SendStringReliable(ushort channelId, string message)可靠字符串
void CustomMessageHandler.SendStringUnreliable(ushort channelId, string message)不可靠字符串
void CustomMessageHandler.SendJsonReliable<T>(ushort channelId, T obj)可靠 JSON
void CustomMessageHandler.SendJsonUnreliable<T>(ushort channelId, T obj)不可靠 JSON
var cm = GetComponent<CustomMessageHandler>();
cm.RegisterChannel(10, (senderId, data) => { });
cm.SendReliable(10, bytes);
cm.SendStringReliable(10, "hello");

NetworkedObject

API说明
uint NetworkedObject.ObjectId { get; }物体 Id;场景 ≥ 1000,运行时 Spawn ≥ 1_000_000
bool NetworkedObject.HasValidId { get; }Id 是否有效
void NetworkedObject.BindObjectId(uint id)绑定运行时 Id
void NetworkedObject.RequestOwnership(bool force)false 无人占用时申请;true 抢占
bool NetworkedObject.IsOwner()本端是否 Owner
bool NetworkedObject.HasOwner()是否已有人持有
void NetworkedObject.SyncNow()立即同步
void NetworkedObject.SetCustomData(byte[] data)附加自定义数据
byte[] NetworkedObject.GetCustomData()读取自定义数据
UnityEvent NetworkedObject.onOwnerChanged所有权变化

NetworkedObjectId

API说明
uint NetworkedObjectId.AllocateRuntimeId()运行时发号,≥ 1_000_000

ObjectSyncHandler

API说明
void ObjectSyncHandler.RequestOwnership(uint objectId, bool force)按 Id 申请所有权
bool ObjectSyncHandler.IsOwner(uint objectId, int playerId)指定玩家是否 Owner
int ObjectSyncHandler.GetOwner(uint objectId)当前 Owner 玩家 Id
void ObjectSyncHandler.DestroyNetworkedObject(uint objectId)销毁网络物体
event Action<uint, GameObject> ObjectSyncHandler.OnObjectSpawned物体已生成
event Action<uint> ObjectSyncHandler.OnObjectDestroyed物体已销毁
event Action<uint, int, int> ObjectSyncHandler.OnOwnershipChanged所有权变化 (id, old, new)
netObj.RequestOwnership(false);
if (netObj.IsOwner()) netObj.SyncNow();

RoomMgr.Instance.RegisterPrefab("MyProp", prefab);
uint id = RoomMgr.Instance.SpawnObject("MyProp", pos, rot, scale, "{}");

MemberHandler

API说明
void MemberHandler.RegisterHandler(UnityAction<List<RoomMember>> action)成员列表变化
void MemberHandler.UnRegisterHandler(UnityAction<List<RoomMember>> action)取消,须同一委托
void MemberHandler.ClearMembers()清空成员

RoomMember

API说明
int RoomMember.PlayerId房间玩家 Id
string RoomMember.DeviceSn设备 SN

TransformHandler

API说明
void TransformHandler.RegisterHandler(UnityAction<PlayerTransformMsg> action)头手位姿回调
void TransformHandler.UnRegisterHandler(UnityAction<PlayerTransformMsg> action)取消,须同一委托
void TransformHandler.TryFlushPending(int playerId, AvatarMono mono)把缓存位姿刷到 Avatar
void TransformHandler.ClearPending()清空缓存位姿
var mh = RoomMgr.Instance.MemberHandler;
mh.RegisterHandler(list => {
    foreach (var m in list) { /* m.PlayerId, m.DeviceSn */ }
});

ContentSyncHandler

API说明
void ContentSyncHandler.RegisterContent(string contentId, IContentController controller)注册播控
void ContentSyncHandler.UnregisterContent(string contentId)取消注册
bool ContentSyncHandler.IsContentRegistered(string contentId)是否已注册
void ContentSyncHandler.Play(string contentId, float seekTime = 0f)全房播放
void ContentSyncHandler.Pause(string contentId)暂停
void ContentSyncHandler.Stop(string contentId)停止
void ContentSyncHandler.Seek(string contentId, float seekTime)跳转到 seekTime 秒
float ContentSyncHandler.GetProgress(string contentId)播放进度 0~1
float ContentSyncHandler.GetPlaybackTime(string contentId)当前播放时间
event Action<ContentSyncMsg> ContentSyncHandler.OnContentSynced收到同步
event Action<string, ContentState> ContentSyncHandler.OnContentStateChanged状态变化

IContentController

API说明
void IContentController.ApplySyncState(ContentSyncMsg msg)应用同步状态
float IContentController.GetCurrentTime()当前播放时间
float IContentController.GetDuration()总时长
ContentState IContentController.GetCurrentState()Idle / Loading / Playing / Paused / Stopped / Finished
var cs = GetComponent<ContentSyncHandler>();
cs.RegisterContent("intro_video", myVideo);
cs.Play("intro_video", 0f);
cs.Seek("intro_video", 12.5f);

AnimationSyncHandler / NetworkedAnimator

API说明
void AnimationSyncHandler.RegisterAnimator(int playerId, NetworkedAnimator networkedAnimator)注册动画同步
void AnimationSyncHandler.UnregisterAnimator(int playerId)取消注册
void NetworkedAnimator.ForceSyncAnimation()立即同步当前动画
void NetworkedAnimator.SetPlayerId(int id)绑定玩家 Id

TimeSyncHandler

API说明
bool TimeSyncHandler.IsSynced { get; }是否已对时
long TimeSyncHandler.ServerTimeMs { get; }估算的服务器时间
void TimeSyncHandler.RequestTimeSync()请求对时
long TimeSyncHandler.LocalToServerTime(long localTimeMs)本地 → 服务器时间
long TimeSyncHandler.ServerToLocalTime(long serverTimeMs)服务器 → 本地时间

AvatarMgr

API说明
void AvatarMgr.SetCatalog(AvatarCatalog catalog)设置形象目录
AvatarCatalog AvatarMgr.Catalog { get; }当前目录
AvatarMono AvatarMgr.GetAvatarRoom(int playerId)按玩家 Id 取
AvatarMono AvatarMgr.GetAvatarRoomFast(int playerId)按玩家 Id 快取
AvatarMono AvatarMgr.GetOrCreateRoom(string sn)按设备 SN 取或创建房间形象
AvatarMono AvatarMgr.GetOrCreateLobby(string sn, string id = "")大厅形象
AvatarMono AvatarMgr.Create(string id = null)按 catalog id 实例化
void AvatarMgr.BindRoomAvatarPlayerId(int playerId, AvatarMono mono)绑定玩家 Id
void AvatarMgr.RemoveRoomAvatar(string sn, int playerId)移除房间形象
void AvatarMgr.ClearAllRoomAvatars()清空房间形象

AvatarMono

API说明
void AvatarMono.SetMember(RoomMember member)绑定房间成员
void AvatarMono.SetDeviceSn(string sn)绑定设备 SN
void AvatarMono.SetNickName(string nickName)设置昵称
void AvatarMono.Calibrate()校准 IK(需实现 IAvatarIkDriver)
void AvatarMono.FadeOnline(bool online)在线淡入 / 离线淡出
bool AvatarMono.LeftHandTracked { get; }远端左手是否在跟踪
bool AvatarMono.RightHandTracked { get; }远端右手是否在跟踪
RoomMember? AvatarMono.RoomMember { get; }绑定的成员

IAvatarIkDriver

API说明
void IAvatarIkDriver.Calibrate()全身 IK 校准
float IAvatarIkDriver.LeftHandWeight { get; set; }左手 IK 权重
float IAvatarIkDriver.RightHandWeight { get; set; }右手 IK 权重

AvatarCatalog

API说明
bool AvatarCatalog.TryResolve(string avatarId, out AvatarData data, out AvatarMono prefab)按 id 解析形象
AvatarMono AvatarCatalog.GetPrefab(string avatarId)取预制体
AvatarMgr.Instance.SetCatalog(myCatalog);
var av = AvatarMgr.Instance.GetAvatarRoom(playerId);
av.SetNickName("P1");
av.Calibrate();

LobbyDeviceOnlineMonitor

API说明
bool LobbyDeviceOnlineMonitor.IsOnline(string sn, long nowMs)大厅设备是否在线
event Action<string, bool> LobbyDeviceOnlineMonitor.OnOnlineChanged在线状态变化 (sn, online)

交互

HandGesturesMgr

API说明
bool HandGesturesMgr.LeftHandTracking { get; }左手是否在跟踪
bool HandGesturesMgr.RightHandTracking { get; }右手是否在跟踪
void HandGesturesMgr.RegisterLeftHandTrackingEvent(UnityAction acquired, UnityAction lost)左手获得 / 丢失跟踪
void HandGesturesMgr.UnRegisterLeftHandTrackingEvent(UnityAction acquired, UnityAction lost)取消,须同一对委托
void HandGesturesMgr.RegisterRightHandTrackingEvent(UnityAction acquired, UnityAction lost)右手获得 / 丢失跟踪
void HandGesturesMgr.UnRegisterRightHandTrackingEvent(UnityAction acquired, UnityAction lost)取消右手
HandGesturesMgr.Instance.RegisterLeftHandTrackingEvent(
    () => { /* acquired */ },
    () => { /* lost */ });

HandGestureHold

API说明
void HandGestureHold.Register()开始检测手势
void HandGestureHold.Unregister()停止检测
UnityEvent HandGestureHold.gesturePerformed手势达成
UnityEvent HandGestureHold.gestureHold持续保持
UnityEvent<float> HandGestureHold.gestureHoldWithTime保持时长(秒)
UnityEvent HandGestureHold.gestureEnded手势结束
float HandGestureHold.minimumHoldTime { get; set; }最短保持时间
hold.Register();
hold.gesturePerformed.AddListener(() => { });
hold.gestureEnded.AddListener(() => { });

CustomGazeInteractor

API说明
bool CustomGazeInteractor.HasHit { get; }是否命中
Vector3 CustomGazeInteractor.HitPoint { get; }命中点
Vector3 CustomGazeInteractor.HitNormal { get; }命中法线
Action<IXRHoverInteractable> CustomGazeInteractor.onDwellTriggered凝视触发

交互组件

类型说明
CustomGrabInteractor抓取
CustomGrabArea抓取区域
HandJointTracker手关节跟踪
HandJointFollower物体跟随关节
HandTag左手 / 右手标记