diff --git a/Runtime/NetworkObject.cs b/Runtime/NetworkObject.cs
index 94bf3a7..5c605ac 100644
--- a/Runtime/NetworkObject.cs
+++ b/Runtime/NetworkObject.cs
@@ -18,8 +18,8 @@ namespace VelNet
[Tooltip("Whether this object's ownership is transferrable. Should be true for player objects.")]
public bool ownershipLocked;
- public bool IsMine => owner != null && owner.isLocal;
-
+ public bool IsMine => owner?.isLocal ?? false;
+
///
/// This is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room
///
@@ -56,7 +56,14 @@ namespace VelNet
}
int index = syncedComponents.IndexOf(component);
- owner.SendMessage(this, index.ToString(), message, reliable);
+ if (index < 0)
+ {
+ Debug.LogError("WAAAAAAAH. NetworkObject doesn't have a reference to this component.", component);
+ }
+ else
+ {
+ owner.SendMessage(this, index.ToString(), message, reliable);
+ }
}
public void SendBytesToGroup(NetworkComponent component, string group, byte[] message, bool reliable = true)
@@ -122,6 +129,7 @@ namespace VelNet
{
c.networkObject = t;
}
+ PrefabUtility.RecordPrefabInstancePropertyModifications(t);
}
// make the sceneNetworkId a new unique value
diff --git a/Runtime/Util/BinaryWriterExtensions.cs b/Runtime/Util/BinaryWriterExtensions.cs
index ed7aba5..f43524d 100644
--- a/Runtime/Util/BinaryWriterExtensions.cs
+++ b/Runtime/Util/BinaryWriterExtensions.cs
@@ -61,5 +61,33 @@ namespace VelNet
return bytes.ToArray();
}
+
+ public static List GetBitmaskValues(this IEnumerable bytes)
+ {
+ List l = new List();
+ foreach (byte b in bytes)
+ {
+ l.AddRange(b.GetBitmaskValues());
+ }
+
+ return l;
+ }
+
+ public static List GetBitmaskValues(this byte b)
+ {
+ List l = new List();
+ for (int i = 0; i < 8; i++)
+ {
+ l.Add(b.GetBitmaskValue(i));
+ }
+
+ return l;
+ }
+
+ public static bool GetBitmaskValue(this byte b, int index)
+ {
+ return (b & (1 << index)) != 0;
+ }
+
}
}
\ No newline at end of file
diff --git a/Runtime/Util/NetworkSerializedObjectStream.cs b/Runtime/Util/NetworkSerializedObjectStream.cs
index a6929f8..161791f 100644
--- a/Runtime/Util/NetworkSerializedObjectStream.cs
+++ b/Runtime/Util/NetworkSerializedObjectStream.cs
@@ -1,4 +1,5 @@
-using System.Collections;
+using System;
+using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Serialization;
@@ -19,12 +20,19 @@ namespace VelNet
{
while (true)
{
- if (IsMine)
+ try
{
- using MemoryStream mem = new MemoryStream();
- using BinaryWriter writer = new BinaryWriter(mem);
- SendState(writer);
- SendBytes(mem.ToArray());
+ if (IsMine)
+ {
+ using MemoryStream mem = new MemoryStream();
+ using BinaryWriter writer = new BinaryWriter(mem);
+ SendState(writer);
+ SendBytes(mem.ToArray());
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e);
}
yield return new WaitForSeconds(1f / serializationRateHz);
diff --git a/Runtime/Util/SyncRigidbody.cs b/Runtime/Util/SyncRigidbody.cs
index 3f65511..5937ff4 100644
--- a/Runtime/Util/SyncRigidbody.cs
+++ b/Runtime/Util/SyncRigidbody.cs
@@ -16,10 +16,10 @@ namespace VelNet
[Tooltip("0 to disable.")]
public float teleportAngle;
- public bool syncKinematic;
- public bool syncGravity;
- public bool syncVelocity;
- public bool syncAngularVelocity;
+ public bool syncKinematic = true;
+ public bool syncGravity = true;
+ public bool syncVelocity = true;
+ public bool syncAngularVelocity = true;
private Vector3 targetPosition;
private Quaternion targetRotation;
diff --git a/Runtime/VelNetManager.cs b/Runtime/VelNetManager.cs
index 295df6e..8a2e447 100644
--- a/Runtime/VelNetManager.cs
+++ b/Runtime/VelNetManager.cs
@@ -34,7 +34,6 @@ namespace VelNet
private Thread clientReceiveThread;
private Thread clientReceiveThreadUDP;
public int userid = -1;
- public string room;
private int messagesReceived = 0;
public readonly Dictionary players = new Dictionary();
@@ -63,7 +62,7 @@ namespace VelNet
public static Action OnConnectedToServer;
public static Action MessageReceived;
- public static Action LoggedIn;
+ public static Action OnLoggedIn;
public static Action RoomsReceived;
public bool connected;
@@ -83,8 +82,23 @@ namespace VelNet
public readonly Dictionary> groups = new Dictionary>();
private VelNetPlayer masterPlayer;
- public static VelNetPlayer LocalPlayer => instance.players.Where(p => p.Value.isLocal).Select(p => p.Value).FirstOrDefault();
+ public static VelNetPlayer LocalPlayer => instance != null ? instance.players.Where(p => p.Value.isLocal).Select(p => p.Value).FirstOrDefault() : null;
public static bool InRoom => LocalPlayer != null && LocalPlayer.room != "-1" && LocalPlayer.room != "";
+ public static string Room => LocalPlayer?.room;
+
+ ///
+ /// The player count in this room.
+ /// -1 if not in a room.
+ ///
+ public static int PlayerCount => instance.players.Count;
+
+ ///
+ /// The player count in all rooms.
+ /// Will include players connected to the server but not in a room?
+ ///
+ public static int PlayerCountInAllRooms => PlayerCount; // TODO hook up to actual player count
+
+ public static bool IsConnected => instance != null && instance.connected && instance.udpConnected;
// Use this for initialization
@@ -151,11 +165,11 @@ namespace VelNet
// when you join the server
case 0:
userid = m.sender;
- Debug.Log("joined server");
+ Debug.Log("Joined server");
try
{
- LoggedIn?.Invoke();
+ OnLoggedIn?.Invoke();
}
// prevent errors in subscribers from breaking our code
catch (Exception e)
@@ -243,24 +257,24 @@ namespace VelNet
// we got a left message, kill it
// change ownership of all objects to master
List deleteObjects = new List();
- foreach (KeyValuePair kvp in objects)
+ foreach ((string key, NetworkObject value) in objects)
{
- if (kvp.Value.owner == players[m.sender]) // the owner is the player that left
+ if (value.owner == players[m.sender]) // the owner is the player that left
{
// if this object has locked ownership, delete it
- if (kvp.Value.ownershipLocked)
+ if (value.ownershipLocked)
{
- deleteObjects.Add(kvp.Value.networkId);
+ deleteObjects.Add(value.networkId);
}
// I'm the local master player, so can take ownership immediately
else if (me.isLocal && me == masterPlayer)
{
- TakeOwnership(kvp.Key);
+ TakeOwnership(key);
}
// the master player left, so everyone should set the owner null (we should get a new master shortly)
else if (players[m.sender] == masterPlayer)
{
- kvp.Value.owner = null;
+ value.owner = null;
}
}
}
@@ -268,7 +282,16 @@ namespace VelNet
// TODO this may check for ownership in the future. We don't need ownership here
deleteObjects.ForEach(NetworkDestroy);
+ VelNetPlayer removedPlayer = players[m.sender];
players.Remove(m.sender);
+ try
+ {
+ OnPlayerLeft?.Invoke(removedPlayer);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e);
+ }
}
else
{
@@ -352,7 +375,7 @@ namespace VelNet
private void OnApplicationQuit()
{
- socketConnection.Close();
+ socketConnection?.Close();
}
///
diff --git a/Runtime/VelNetPlayer.cs b/Runtime/VelNetPlayer.cs
index fae5623..1152432 100644
--- a/Runtime/VelNetPlayer.cs
+++ b/Runtime/VelNetPlayer.cs
@@ -9,8 +9,6 @@ namespace VelNet
public class VelNetPlayer
{
public int userid;
- public string username;
-
public string room;
public bool isLocal;
@@ -69,7 +67,7 @@ namespace VelNet
switch (sections[0])
{
- case "5": //sync update for an object I may own
+ case "5": // sync update for an object I may own
{
string objectKey = sections[1];
string identifier = sections[2];
@@ -85,7 +83,7 @@ namespace VelNet
break;
}
- case "6": //I'm trying to take ownership of an object
+ case "6": // I'm trying to take ownership of an object
{
string networkId = sections[1];