using System.Collections; using System.Collections.Generic; using Unity.Collections; using Unity.Netcode; using UnityEngine; namespace Rokid.MRC { public class ClientRequest : INetworkSerializable { public enum OpType { StartBuild, CancelBuild, ChangeCoord, ChangeScreenOrit, } public ulong ClientId; public ARCalibrationMode CalibrationMode; public OpType op; public SpacePose Pose; public bool isPortrait; public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { serializer.SerializeValue(ref ClientId); serializer.SerializeValue(ref op); serializer.SerializeValue(ref CalibrationMode); serializer.SerializeValue(ref Pose); serializer.SerializeValue(ref isPortrait); } } public class ServerRequest : INetworkSerializable { public enum OpType { ChangeCoord, StartStream, } public OpType op; public SpacePose Pose; public string msg; public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { serializer.SerializeValue(ref op); serializer.SerializeValue(ref Pose); serializer.SerializeValue(ref msg); } } public class ServerMessageDispatcher : Singleton { public ScreenOrientation clientScreenOrientation; public override void Init() { base.Init(); //NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(nameof(StartBuild), StartBuild); if(NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { NetworkManager.Singleton.CustomMessagingManager.OnUnnamedMessage += OnReceivedMessage; } } //所有客户端的空间坐标系 public List ClientSpacePoseList = new List(); //所有服务端的空间坐标系 public List ServerSpacePoseList = new List(); //更新所有客户端的坐标系 public void UpdateClientSpaceCoord(ulong clientId, SpacePose spacePose) { //服务端更新该SpacePose for(int i = 0;i < ClientSpacePoseList.Count;i++) { if(ClientSpacePoseList[i].ClientId == spacePose.ClientId) { ClientSpacePoseList[i] = spacePose; return; } } //服务端添加该SpacePose ClientSpacePoseList.Add(spacePose); } //更新所有服务端坐标系 public void UpdateServerSpaceCoord(ulong clientId, SpacePose serverSpacePose) { bool isUpdate = false; for(int i = 0;i < ServerSpacePoseList.Count;i++) { if(ServerSpacePoseList[i].ClientId == serverSpacePose.ClientId) { ServerSpacePoseList[i] = serverSpacePose; isUpdate = true; } } if(!isUpdate) { ServerSpacePoseList.Add(serverSpacePose); } //发包给手机端 SyncServerPoseToClient(clientId, serverSpacePose); } //眼镜端同步位姿到手机端 private void SyncServerPoseToClient(ulong clientId, SpacePose pose) { FastBufferWriter writer = new FastBufferWriter(1100, Allocator.Temp); using(writer) { ServerRequest serverReq = new ServerRequest(); serverReq.op = ServerRequest.OpType.ChangeCoord; serverReq.Pose = pose; serverReq.msg = MRCUtility.GetWirelessIP(AddressType.IPv4); //写入消息体 writer.WriteValueSafe(serverReq); //NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, writer, NetworkDelivery.ReliableFragmentedSequenced); NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, writer); } } public void SyncStartStream(ulong clientId) { FastBufferWriter writer = new FastBufferWriter(1100, Allocator.Temp); using(writer) { ServerRequest serverReq = new ServerRequest(); serverReq.op = ServerRequest.OpType.StartStream; serverReq.msg = MRCUtility.GetWirelessIP(AddressType.IPv4); //写入消息体 writer.WriteValueSafe(serverReq); NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, writer); } } private void OnReceivedMessage(ulong clientId, FastBufferReader reader) { //服务端收到数据 reader.ReadValueSafe(out ClientRequest clientReq); if(clientReq.op == ClientRequest.OpType.StartBuild) { if(clientReq.CalibrationMode == ARCalibrationMode.FaceTrack) { //TODO,暂时先用Confirm界面来提示 UIManager.Instance.ShowConfirm( LocalizationMgr.Instance.GetTextByKey("BuildTitle"), string.Format(LocalizationMgr.Instance.GetTextByKey("BuildReq"), PlayerManager.Instance.GetPlayerData(clientReq.ClientId)?.PlayerName), ConfirmType.None); } else if(clientReq.CalibrationMode == ARCalibrationMode.SelfCalibration) { //自构建,创建手机模型 ResourceManager.Instance.CreatePhoneAnchor(); MRCDriver.Instance.SelfCalibrationPhone.gameObject.SetActive(true); } } else if(clientReq.op == ClientRequest.OpType.CancelBuild) { UIManager.Instance.ClosePanel(UIType.Confirm); } else if(clientReq.op == ClientRequest.OpType.ChangeCoord) { //更新客户端Pose列表 UpdateClientSpaceCoord(clientId, clientReq.Pose); SpacePose serverSpacePose = default(SpacePose); if(clientReq.CalibrationMode == ARCalibrationMode.FaceTrack) { //更新服务端Pose列表 serverSpacePose = new SpacePose(clientId, Camera.main.transform.position, Camera.main.transform.rotation, clientReq.CalibrationMode); } else if(clientReq.CalibrationMode == ARCalibrationMode.SelfCalibration) { serverSpacePose = new SpacePose(clientId, MRCDriver.Instance.SelfCalibrationPhone.position, MRCDriver.Instance.SelfCalibrationPhone.rotation, clientReq.CalibrationMode); MRCDriver.Instance.SelfCalibrationPhone.gameObject.SetActive(false); } //同步眼镜端位姿 UpdateServerSpaceCoord(clientId, serverSpacePose); //通知构建提示界面关闭 MessageCenter.SendMessage(GlobalDefine.SpaceBuildEnd, null); //CompositionManager.Instance.StartConnectStream(); } else if(clientReq.op == ClientRequest.OpType.ChangeScreenOrit) { //横竖屏切换 Debug.Log($"ChangeScreenOrit Is Portrait : {clientReq.isPortrait}"); CameraController.Instance.ChangeFollowTargetOrientation(clientReq.isPortrait); } } } }