using Byn.Awrtc; using Byn.Awrtc.Unity; using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.XR.Interaction.Toolkit; using WIFramework.Util; using Random = UnityEngine.Random; public class WebRTCManager : MonoBehaviour { #region LocalDefine enum DataCode { Raw, LeftHand, RightHand, HandRay, Input } enum ParsingOrder { DataCode, ID, Pos, Rot, } #endregion #region Variables public Player prefab_Player; public Player myPlayer; public GameObject uVideoPrefab; public Dictionary playerTable = new Dictionary(); public Dictionary videoTable = new Dictionary(); public Dictionary leftHandTable = new Dictionary(); public Dictionary rightHandTable = new Dictionary(); public Texture2D texture_NoImage; #endregion // ¼Õ º¸À̱â Ãß°¡ //public XRController l_hand; //public XRController r_hand; #region UnityMethods public void Awake() { //prefab_Player = Resources.Load("Player").GetComponent(); myPlayer = SpawnPlayer(); } #endregion #region CallEvent public void CallEvent(object sender, CallEventArgs e) { switch (e.Type) { case CallEventType.CallAccepted: var ca = e as CallAcceptedEventArgs; Debug.Log($"On New Call : {ca.ConnectionId}"); CallEvent_NewCall(ca); break; case CallEventType.CallEnded: var ce = e as CallEndedEventArgs; Debug.Log($"On Call Ended : {ce.ConnectionId}"); CallEvent_Ended(ce); break; case CallEventType.ListeningFailed: Debug.Log($"Listening Failed!!"); CallEvent_Reset(); break; case CallEventType.ConnectionFailed: ErrorEventArgs eea = e as ErrorEventArgs; Debug.LogError(eea.Info); CallEvent_Reset(); break; case CallEventType.FrameUpdate: FrameUpdateEventArgs frameargs = e as FrameUpdateEventArgs; UpdateFrame(frameargs); break; case CallEventType.Message: MessageEventArgs mea = e as MessageEventArgs; Debug.Log($"Receive Message From={mea.ConnectionId}"); CallMessageParsing(mea); break; case CallEventType.WaitForIncomingCall: WaitForIncomingCallEventArgs wic = e as WaitForIncomingCallEventArgs; Debug.Log($"Wait For Incomming Call Event... {wic.Address}"); break; } } private void UpdateFrame(FrameUpdateEventArgs args) { if (videoTable.ContainsKey(args.ConnectionId)) { VideoData videoData = videoTable[args.ConnectionId]; //make sure not to overwrite / destroy our texture for missing image data if (videoData.image.texture == texture_NoImage) videoData.image.texture = null; bool mirror = args.IsRemote == false; //converts the frame data to a texture and sets it to the raw image UnityMediaHelper.UpdateRawImageTransform(videoData.image, args.Frame, mirror); videoData.texture = videoData.image.texture as Texture2D; } } void CleanupCall() { if (myPlayer.myCall == null) return; //Debug.Log("Destroying call!"); myPlayer.myCall.Dispose(); myPlayer.myCall = null; //Debug.Log("Call destroyed"); } public void CallEvent_Reset() { foreach (var v in videoTable) { Destroy(v.Value.uiObject); if (v.Value.texture != null) Destroy(v.Value.texture); } videoTable.Clear(); CleanupCall(); } private void CallEvent_NewCall(CallAcceptedEventArgs args) { if (!playerTable.ContainsKey(args.ConnectionId)) { var p = FindPlayer(args.ConnectionId); } myPlayer.Send(GetRawData(myPlayer)); //myPlayer.Send(GetLeftHandRawData(myLeftHand)); //myPlayer.Send(GetRightHandRawData(myRightHand)); } private void CallEvent_Ended(CallEndedEventArgs args) { Debug.Log($"On Call End : {args.ConnectionId}"); VideoData data; if (videoTable.TryGetValue(args.ConnectionId, out data)) { if (data.texture != null) Destroy(data.texture); Destroy(data.uiObject); videoTable.Remove(args.ConnectionId); } OnUserLeft(args.ConnectionId); } private void OnUserLeft(ConnectionId id) { Debug.Log($"On User Left : {id}"); Debug.Log($"Try Get Left User..."); if (!playerTable.ContainsKey(id)) { Debug.Log($"On User Left Into Wrong Connection({id}) Id."); return; } var target = playerTable[id]; Debug.Log($"Find Left User. connectionId={id}, userName={target.userName}"); Debug.Log($"Remove Left User Datas..."); playerTable.Remove(id); Debug.Log($"Remove Left User From Player Table"); videoTable.Remove(id); Debug.Log($"Remove Left User Video Frame"); Destroy(target.gameObject); Debug.Log($"Remove Left User Objects"); } #endregion #region DataParsing public string GetRawData(Player p) { var t = p.transform; return $"{DataCode.Raw}/{p.userName}/" + $"{t.position.x},{t.position.y},{t.position.z}/" + $"{t.rotation.x},{t.rotation.y},{t.rotation.z},{t.rotation.w}"; } public string GetLeftHandRawData(GameObject p, string userName) { var t = p.transform; return $"{DataCode.LeftHand}/{userName}/" + $"{t.position.x},{t.position.y},{t.position.z}/" + $"{t.rotation.x},{t.rotation.y},{t.rotation.z},{t.rotation.w}"; } public string GetRightHandRawData(GameObject p, string userName) { var t = p.transform; return $"{DataCode.RightHand}/{userName}/" + $"{t.position.x},{t.position.y},{t.position.z}/" + $"{t.rotation.x},{t.rotation.y},{t.rotation.z},{t.rotation.w}"; } public string GetHandRayData(string OnOff, string userName) { return $"{DataCode.HandRay}/{userName}/{OnOff}"; } public Player SpawnPlayer(bool isDummy = false) { var player = Instantiate(prefab_Player); player.Initialize(isDummy); return player; } void CallMessageParsing(MessageEventArgs args) { /* if(args.Content == "On") { var targetPlayer = FindHandRayPlayer(args.ConnectionId); targetPlayer.GetComponentInChildren().DummyOnOff(true); Debug.Log("´õ¹Ì ray on"); } else if(args.Content == "Off") { var targetPlayer = FindHandRayPlayer(args.ConnectionId); targetPlayer.GetComponentInChildren().DummyOnOff(false); Debug.Log("´õ¹Ì ray off"); } else */ { var dataSplit = args.Content.Split('/'); DataCode dataType = (DataCode)Enum.Parse(typeof(DataCode), dataSplit[0]); Debug.Log($"Call Message Type = {dataType}"); switch (dataType) { case DataCode.Raw: ExecuteRawData(args, dataSplit); break; case DataCode.LeftHand: ExecuteLeftHandData(args, dataSplit); break; case DataCode.RightHand: ExecuteRightHandData(args, dataSplit); break; case DataCode.HandRay: ExecuteHandRayData(args, dataSplit, dataSplit[2]); Debug.Log("DataCode °ªÀÌ" + dataSplit[0]); Debug.Log("UserName °ªÀÌ" + dataSplit[1]); Debug.Log("OnOff °ªÀÌ" + dataSplit[2]); break; case DataCode.Input: ExecuteInputData(dataSplit); break; } } } private void ExecuteRawData(MessageEventArgs args, string[] dataSplit) { //Debug.Log($"Execute Raw Data..."); var id = dataSplit[(int)ParsingOrder.ID]; Debug.Log($"Parsing Id={id}"); var targetPlayer = FindPlayer(args, id); Debug.Log($"Parsing Player={targetPlayer.userName}"); var rawPos = dataSplit[(int)ParsingOrder.Pos].Split(','); Vector3 pos = new Vector3(float.Parse(rawPos[0]), float.Parse(rawPos[1]), float.Parse(rawPos[2])); Debug.Log($"Parsing Pos={pos}"); var rawRot = dataSplit[(int)ParsingOrder.Rot].Split(','); Quaternion rot = new Quaternion(float.Parse(rawRot[0]), float.Parse(rawRot[1]), float.Parse(rawRot[2]), float.Parse(rawRot[3])); Debug.Log($"Parsing Rot={rot}"); targetPlayer.transform.position = pos; targetPlayer.transform.rotation = rot; } private void ExecuteLeftHandData(MessageEventArgs args, string[] dataSplit) { var id = dataSplit[(int)ParsingOrder.ID]; Debug.Log($"Parsing LeftHand Id={id}"); var target = FindLeftHand(args, id); var rawPos = dataSplit[(int)ParsingOrder.Pos].Split(','); Vector3 pos = new Vector3((float)-0.033, (float)1.3176, (float)0); pos = pos + new Vector3(float.Parse(rawPos[0]), float.Parse(rawPos[1]), float.Parse(rawPos[2])); Debug.Log($"Parsing LeftHand Pos={pos}"); var rawRot = dataSplit[(int)ParsingOrder.Rot].Split(','); Quaternion rot = new Quaternion(float.Parse(rawRot[0]), float.Parse(rawRot[1]), float.Parse(rawRot[2]), float.Parse(rawRot[3])); Debug.Log($"Parsing LeftHand Rot={rot}"); target.transform.position = pos; target.transform.rotation = rot; } private void ExecuteRightHandData(MessageEventArgs args, string[] dataSplit) { var id = dataSplit[(int)ParsingOrder.ID]; Debug.Log($"Parsing RightHand Id={id}"); var target = FindRightHand(args, id); var rawPos = dataSplit[(int)ParsingOrder.Pos].Split(','); Vector3 pos = new Vector3((float)-0.033, (float)1.3176, (float)0); pos = pos + new Vector3(float.Parse(rawPos[0]), float.Parse(rawPos[1]), float.Parse(rawPos[2])); Debug.Log($"Parsing RightHand Pos={pos}"); var rawRot = dataSplit[(int)ParsingOrder.Rot].Split(','); Quaternion rot = new Quaternion(float.Parse(rawRot[0]), float.Parse(rawRot[1]), float.Parse(rawRot[2]), float.Parse(rawRot[3])); Debug.Log($"Parsing RightHand Rot={rot}"); target.transform.position = pos; target.transform.rotation = rot; } private void ExecuteHandRayData(MessageEventArgs args, string[] dataSplit, string onOff) { var id = dataSplit[(int)ParsingOrder.ID]; Debug.Log($"Parsing HandRay Id={id}"); var targetPlayer = FindHandRayPlayer(args, id); //¿©±â¼­ Ä¿³Ø¼Ç ¾ÆÀ̵𸸠Á¦´ë·Î µé¾î°¡¸é ³¡ Debug.Log("PlayerÀÇ Id°¡" + id); if (onOff == "On") { targetPlayer.GetComponentInChildren().DummyOnOff(true); Debug.Log("´õ¹Ì ray on"); } else if (onOff == "Off") { targetPlayer.GetComponentInChildren().DummyOnOff(false); Debug.Log("´õ¹Ì ray off"); } } public enum CustomKeyCode { None, W, S, A, D } public CustomKeyCode CustomKeyCodeMatching(KeyCode keyCode) { if (keyCode == KeyCode.W) return CustomKeyCode.W; if (keyCode == KeyCode.A) return CustomKeyCode.A; if (keyCode == KeyCode.S) return CustomKeyCode.S; if (keyCode == KeyCode.D) return CustomKeyCode.D; return CustomKeyCode.None; } /// /// dataType/Id/CustomKeyCode /// /// private void ExecuteInputData(string[] dataSplit) { Debug.Log($"Excute Input Data..."); throw new NotImplementedException(); } /// /// Parsing Rule /// DataType/ID/x,y,z/x,y,z,w /// [0]/[1]/[2]/[3] /// enum/string/vector3/quarternion /// #endregion #region Player public void MutePlayer(Player p, bool isMute) { p.myCall.SetMute(isMute); } public void MediaConfigChange_VideoOutput(Player p, bool isOn) { p.mediaConfig.Video = isOn; } public void MediaConfigChange_AudioOutput(Player p, bool isOn) { p.mediaConfig.Audio = isOn; } internal Player CreateDummyPlayer() { Debug.Log($"Create Dummy Player"); var p = SpawnPlayer(true); return p; } public Player FindPlayer(ConnectionId id) { Debug.Log($"Find Player ConnectionId = {id}"); Debug.Log($"Try Get ConnectionId({id})"); if (playerTable.ContainsKey(id)) { return playerTable[id]; } Debug.Log($"Can`t Find ConnectionId({id})"); var dummy = CreateDummyPlayer(); dummy.Initialize(true); playerTable.Add(id, dummy); videoTable.Add(id, dummy.videoData); Debug.Log($"Add New DummyPlayer. connectionId={id}, playerName={name}"); var result = playerTable[id]; return result; } internal Player FindPlayer(MessageEventArgs args, string name) { var result = FindPlayer(args.ConnectionId); result.SetName(name); return result; } public GameObject FindLeftHand(ConnectionId id) { Debug.Log($"Find LeftHand ConnectionId = {id}"); if (leftHandTable.ContainsKey(id)) { return leftHandTable[id]; } var dummyHand = playerTable[id].SendLeftHand(); leftHandTable.Add(id, dummyHand); var result = leftHandTable[id]; return result; } internal GameObject FindLeftHand(MessageEventArgs args, string name) { var result = FindLeftHand(args.ConnectionId); return result; } public GameObject FindRightHand(ConnectionId id) { Debug.Log($"Find RightHand ConnectionId = {id}"); if (rightHandTable.ContainsKey(id)) { return rightHandTable[id]; } var dummyHand = playerTable[id].SendRightHand(); rightHandTable.Add(id, dummyHand); var result = rightHandTable[id]; return result; } internal GameObject FindRightHand(MessageEventArgs args, string name) { var result = FindRightHand(args.ConnectionId); return result; } public Player FindHandRayPlayer(ConnectionId id) { var result = playerTable[id]; return result; } internal Player FindHandRayPlayer(MessageEventArgs args, string name) { var result = FindHandRayPlayer(args.ConnectionId); return result; } #endregion }