From 260cd891dbc8469628e25abf4619d78290d422db Mon Sep 17 00:00:00 2001 From: Anton Franzluebbers Date: Fri, 7 Jan 2022 19:20:21 -0500 Subject: [PATCH] fixed group messages, fixed some errors with players leaving --- Runtime/NetworkComponent.cs | 2 +- Runtime/NetworkObject.cs | 2 +- Runtime/{ => Util}/NetworkSerializedObject.cs | 0 .../NetworkSerializedObject.cs.meta | 0 Runtime/VelNetManager.cs | 29 +++++----- Runtime/{NetworkPlayer.cs => VelNetPlayer.cs} | 6 +- ...orkPlayer.cs.meta => VelNetPlayer.cs.meta} | 0 .../VelNetDissonancePlayer.cs | 43 ++++++++++++--- Samples~/Example/PlayerController.cs | 55 ++++++++++--------- Samples~/Example/PlayerPrefab.prefab | 24 ++++++-- Samples~/Example/test.unity | 4 +- package.json | 2 +- 12 files changed, 110 insertions(+), 57 deletions(-) rename Runtime/{ => Util}/NetworkSerializedObject.cs (100%) rename Runtime/{ => Util}/NetworkSerializedObject.cs.meta (100%) rename Runtime/{NetworkPlayer.cs => VelNetPlayer.cs} (97%) rename Runtime/{NetworkPlayer.cs.meta => VelNetPlayer.cs.meta} (100%) diff --git a/Runtime/NetworkComponent.cs b/Runtime/NetworkComponent.cs index 9b859bf..f1a9b31 100644 --- a/Runtime/NetworkComponent.cs +++ b/Runtime/NetworkComponent.cs @@ -6,7 +6,7 @@ namespace VelNet { public NetworkObject networkObject; protected bool IsMine => networkObject != null && networkObject.owner != null && networkObject.owner.isLocal; - protected NetworkPlayer Owner => networkObject != null ? networkObject.owner : null; + protected VelNetPlayer Owner => networkObject != null ? networkObject.owner : null; /// /// call this in child classes to send a message to other people diff --git a/Runtime/NetworkObject.cs b/Runtime/NetworkObject.cs index 1193745..3ed03a7 100644 --- a/Runtime/NetworkObject.cs +++ b/Runtime/NetworkObject.cs @@ -10,7 +10,7 @@ namespace VelNet public class NetworkObject : MonoBehaviour { [Header("NetworkObject properties")] - public NetworkPlayer owner; + public VelNetPlayer owner; public bool ownershipLocked; public bool IsMine => owner != null && owner.isLocal; diff --git a/Runtime/NetworkSerializedObject.cs b/Runtime/Util/NetworkSerializedObject.cs similarity index 100% rename from Runtime/NetworkSerializedObject.cs rename to Runtime/Util/NetworkSerializedObject.cs diff --git a/Runtime/NetworkSerializedObject.cs.meta b/Runtime/Util/NetworkSerializedObject.cs.meta similarity index 100% rename from Runtime/NetworkSerializedObject.cs.meta rename to Runtime/Util/NetworkSerializedObject.cs.meta diff --git a/Runtime/VelNetManager.cs b/Runtime/VelNetManager.cs index b46ee81..8f845b3 100644 --- a/Runtime/VelNetManager.cs +++ b/Runtime/VelNetManager.cs @@ -35,18 +35,18 @@ namespace VelNet public string room; private int messagesReceived = 0; - public readonly Dictionary players = new Dictionary(); + public readonly Dictionary players = new Dictionary(); - public Action OnJoinedRoom; - public Action OnPlayerJoined; - public Action OnPlayerLeft; + public Action OnJoinedRoom; + public Action OnPlayerJoined; + public Action OnPlayerLeft; public List prefabs = new List(); public NetworkObject[] sceneObjects; public List deletedSceneObjects = new List(); public readonly Dictionary objects = new Dictionary(); //maintains a list of all known objects on the server (ones that have ids) - private NetworkPlayer masterPlayer; - public static NetworkPlayer LocalPlayer => instance.players.Where(p => p.Value.isLocal).Select(p=>p.Value).FirstOrDefault(); + private VelNetPlayer masterPlayer; + public static VelNetPlayer LocalPlayer => instance.players.Where(p => p.Value.isLocal).Select(p=>p.Value).FirstOrDefault(); @@ -115,7 +115,7 @@ namespace VelNet if (m.text != "") { - NetworkPlayer player = new NetworkPlayer + VelNetPlayer player = new VelNetPlayer { isLocal = true, userid = m.sender, @@ -128,12 +128,13 @@ namespace VelNet } else // not for me, a player is joining or leaving { - NetworkPlayer me = players[userid]; + VelNetPlayer me = players[userid]; if (me.room != m.text) { // we got a left message, kill it // change ownership of all objects to master + List deleteObjects = new List(); foreach (KeyValuePair kvp in objects) { if (kvp.Value.owner == players[m.sender]) // the owner is the player that left @@ -141,8 +142,7 @@ namespace VelNet // if this object has locked ownership, delete it if (kvp.Value.ownershipLocked) { - // TODO this may check for ownership in the future. We don't need ownership here - DeleteNetworkObject(kvp.Value.networkId); + deleteObjects.Add(kvp.Value.networkId); } // I'm the local master player, so can take ownership immediately else if (me.isLocal && me == masterPlayer) @@ -156,13 +156,16 @@ namespace VelNet } } } + + // TODO this may check for ownership in the future. We don't need ownership here + deleteObjects.ForEach(DeleteNetworkObject); players.Remove(m.sender); } else { // we got a join message, create it - NetworkPlayer player = new NetworkPlayer + VelNetPlayer player = new VelNetPlayer { isLocal = false, room = m.text, @@ -524,7 +527,7 @@ namespace VelNet public static void InstantiateNetworkObject(string prefabName) { - NetworkPlayer localPlayer = LocalPlayer; + VelNetPlayer localPlayer = LocalPlayer; NetworkObject prefab = instance.prefabs.Find(p => p.name == prefabName); if (prefab == null) { @@ -541,7 +544,7 @@ namespace VelNet instance.SendTo(MessageType.OTHERS, "7," + newObject.networkId + "," + prefabName); } - public static void SomebodyInstantiatedNetworkObject(string networkId, string prefabName, NetworkPlayer owner) + public static void SomebodyInstantiatedNetworkObject(string networkId, string prefabName, VelNetPlayer owner) { NetworkObject prefab = instance.prefabs.Find(p => p.name == prefabName); if (prefab == null) return; diff --git a/Runtime/NetworkPlayer.cs b/Runtime/VelNetPlayer.cs similarity index 97% rename from Runtime/NetworkPlayer.cs rename to Runtime/VelNetPlayer.cs index f84dafe..5d6f434 100644 --- a/Runtime/NetworkPlayer.cs +++ b/Runtime/VelNetPlayer.cs @@ -6,7 +6,7 @@ namespace VelNet /// /// Represents a network player /// - public class NetworkPlayer + public class VelNetPlayer { public int userid; public string username; @@ -26,13 +26,13 @@ namespace VelNet private bool isMaster; - public NetworkPlayer() + public VelNetPlayer() { manager = VelNetManager.instance; manager.OnPlayerJoined += HandlePlayerJoined; } - public void HandlePlayerJoined(NetworkPlayer player) + public void HandlePlayerJoined(VelNetPlayer player) { //if this is the local player, go through the objects that I own, and send instantiation messages for the ones that have prefab names if (isLocal) diff --git a/Runtime/NetworkPlayer.cs.meta b/Runtime/VelNetPlayer.cs.meta similarity index 100% rename from Runtime/NetworkPlayer.cs.meta rename to Runtime/VelNetPlayer.cs.meta diff --git a/Samples~/DissonanceIntegration/VelNetDissonancePlayer.cs b/Samples~/DissonanceIntegration/VelNetDissonancePlayer.cs index 72b9a38..1e51f58 100644 --- a/Samples~/DissonanceIntegration/VelNetDissonancePlayer.cs +++ b/Samples~/DissonanceIntegration/VelNetDissonancePlayer.cs @@ -28,6 +28,10 @@ namespace VelNet public bool IsTracking => true; private static readonly List allPlayers = new List(); + + /// + /// Only sends voice data to players in this list + /// public List closePlayers = new List(); [Tooltip("Maximum distance to transmit voice data. 0 to always send voice to all players.")] @@ -47,15 +51,30 @@ namespace VelNet if (comms == null) { Debug.LogError("No VelCommsNetwork found. Make sure there is one in your scene.", this); - return; } + } + private void OnEnable() + { // add ourselves to the global list of all players in the scene if (!allPlayers.Contains(this)) { allPlayers.Add(this); } + else + { + Debug.LogError("We're already in the player list 🐭", this); + } + } + private void OnDisable() + { + // remove ourselves from the global list of all players in the scene + allPlayers.Remove(this); + } + + private void Start() + { if (IsMine) { SetDissonanceID(comms.dissonanceId); @@ -71,7 +90,6 @@ namespace VelNet writer.Write(dissonanceID); SendBytes(mem.ToArray()); }; - VelNetManager.instance.SetupMessageGroup("close", closePlayers.ToArray()); } } @@ -83,10 +101,11 @@ namespace VelNet using MemoryStream mem = new MemoryStream(); using BinaryWriter writer = new BinaryWriter(mem); writer.Write((byte)MessageType.AudioData); - writer.Write(BitConverter.GetBytes(lastAudioId++)); + writer.Write(lastAudioId++); writer.Write(data.ToArray()); // send voice data unreliably - SendBytesToGroup("close", mem.ToArray(), false); + // SendBytes(mem.ToArray(), false); + SendBytesToGroup("voice", mem.ToArray()); } /// @@ -147,12 +166,21 @@ namespace VelNet if (closePlayerListChanged) { - VelNetManager.instance.SetupMessageGroup("close", closePlayers); + VelNetManager.instance.SetupMessageGroup("voice", closePlayers); + } + } + else + { + int lastLength = closePlayers.Count; + closePlayers = allPlayers.Where(p => p != this).Select(p => p.Owner.userid).ToList(); + if (closePlayers.Count != lastLength) + { + VelNetManager.instance.SetupMessageGroup("voice", closePlayers); } } - //handle dissonance comms + // handle dissonance comms //if we're not speaking, and the comms say we are, send a speaking event, which will be received on other network players and sent to their comms accordingly if (comms.dissonanceComms.FindPlayer(dissonanceID)?.IsSpeaking != isSpeaking) //unfortunately, there does not seem to be an event for this @@ -194,6 +222,7 @@ namespace VelNet if (dissonanceID == "") // I don't have this yet { dissonanceID = reader.ReadString(); + // tell the comms network that this player joined the channel comms.SetPlayerJoined(dissonanceID); // tell dissonance comms.dissonanceComms.TrackPlayerPosition(this); // tell dissonance to track the remote player @@ -203,7 +232,7 @@ namespace VelNet } case 2: // speaking state { - if (message[0] == 0) + if (message[1] == 0) { comms.SetPlayerStoppedSpeaking(dissonanceID); isSpeaking = false; diff --git a/Samples~/Example/PlayerController.cs b/Samples~/Example/PlayerController.cs index f1886ba..b33a15f 100644 --- a/Samples~/Example/PlayerController.cs +++ b/Samples~/Example/PlayerController.cs @@ -4,7 +4,7 @@ using UnityEngine; namespace VelNet { - public class PlayerController : NetworkSerializedObject + public class PlayerController : NetworkComponent { public Vector3 targetPosition; public Quaternion targetRotation; @@ -13,12 +13,13 @@ namespace VelNet // Update is called once per frame private void Update() { - if (!IsMine) - { - transform.position = Vector3.Lerp(transform.position, targetPosition, .1f); - transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f); - } - else + // if (!IsMine) + // { + // transform.position = Vector3.Lerp(transform.position, targetPosition, .1f); + // transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f); + // } + // else + if (IsMine) { Vector3 movement = new Vector3(); movement.x += Input.GetAxis("Horizontal"); @@ -53,25 +54,29 @@ namespace VelNet } } - - protected override byte[] SendState() + // + // protected override byte[] SendState() + // { + // using MemoryStream mem = new MemoryStream(); + // using BinaryWriter writer = new BinaryWriter(mem); + // + // writer.Write(transform.position); + // writer.Write(transform.rotation); + // + // return mem.ToArray(); + // } + // + // protected override void ReceiveState(byte[] message) + // { + // using MemoryStream mem = new MemoryStream(message); + // using BinaryReader reader = new BinaryReader(mem); + // + // targetPosition = reader.ReadVector3(); + // targetRotation = reader.ReadQuaternion(); + // } + public override void ReceiveBytes(byte[] message) { - using MemoryStream mem = new MemoryStream(); - using BinaryWriter writer = new BinaryWriter(mem); - - writer.Write(transform.position); - writer.Write(transform.rotation); - - return mem.ToArray(); - } - - protected override void ReceiveState(byte[] message) - { - using MemoryStream mem = new MemoryStream(message); - using BinaryReader reader = new BinaryReader(mem); - - targetPosition = reader.ReadVector3(); - targetRotation = reader.ReadQuaternion(); + throw new System.NotImplementedException(); } } } \ No newline at end of file diff --git a/Samples~/Example/PlayerPrefab.prefab b/Samples~/Example/PlayerPrefab.prefab index e4b77af..ee6b3e4 100644 --- a/Samples~/Example/PlayerPrefab.prefab +++ b/Samples~/Example/PlayerPrefab.prefab @@ -15,6 +15,7 @@ GameObject: - component: {fileID: 9102273340480352682} - component: {fileID: -4404668399269848200} - component: {fileID: 1181612843795795320} + - component: {fileID: 7564913803199044469} m_Layer: 0 m_Name: PlayerPrefab m_TagString: Untagged @@ -31,7 +32,7 @@ Transform: m_GameObject: {fileID: 6139051692386484099} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalScale: {x: 0.1, y: 0.1, z: 0.1} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -117,6 +118,7 @@ MonoBehaviour: syncedComponents: - {fileID: -4404668399269848200} - {fileID: 1181612843795795320} + - {fileID: 7564913803199044469} --- !u!114 &-4404668399269848200 MonoBehaviour: m_ObjectHideFlags: 0 @@ -130,7 +132,6 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: networkObject: {fileID: 9102273340480352682} - serializationRateHz: 30 targetPosition: {x: 0, y: 0, z: 0} targetRotation: {x: 0, y: 0, z: 0, w: 0} --- !u!114 &1181612843795795320 @@ -147,7 +148,22 @@ MonoBehaviour: m_EditorClassIdentifier: networkObject: {fileID: 9102273340480352682} dissonanceID: - targetPosition: {x: 0, y: 0, z: 0} - targetRotation: {x: 0, y: 0, z: 0, w: 0} closePlayers: maxDistance: 0 +--- !u!114 &7564913803199044469 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3f1f9b0bbd93a484a987c51f1107ebe5, type: 3} + m_Name: + m_EditorClassIdentifier: + networkObject: {fileID: 9102273340480352682} + serializationRateHz: 30 + targetPosition: {x: 0, y: 0, z: 0} + targetRotation: {x: 0, y: 0, z: 0, w: 0} + smoothness: 0.1 diff --git a/Samples~/Example/test.unity b/Samples~/Example/test.unity index bda34bd..4ef181e 100644 --- a/Samples~/Example/test.unity +++ b/Samples~/Example/test.unity @@ -1834,7 +1834,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 03a4d4e1a7fd74c7ab2eccca4ce168db, type: 3} m_Name: m_EditorClassIdentifier: - host: neko.ugavel.com + host: 129.159.107.234 port: 3290 udpConnected: 0 userid: -1 @@ -3406,7 +3406,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} propertyPath: m_LocalPosition.y - value: 0 + value: 2 objectReference: {fileID: 0} - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} propertyPath: m_LocalPosition.z diff --git a/package.json b/package.json index 9e4bd8d..0ce5853 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "edu.uga.engr.vel.velnet", "displayName": "VelNet", - "version": "1.0.3", + "version": "1.0.4", "unity": "2019.1", "description": "A custom networking library for Unity.", "keywords": [