diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs
index 086ea6d..2004090 100644
--- a/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs
+++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs
@@ -27,7 +27,15 @@ namespace VelNet
public string networkId;
///
- /// This is generated at editor time and used to generated the network id at runtime.
+ /// This is used internally to handle spawning of objects for players that joined late.
+ /// This way objects can be spawned in a static location
+ ///
+ internal bool instantiatedWithTransform = false;
+ internal Vector3 initialPosition;
+ internal Quaternion initialRotation;
+
+ ///
+ /// This is generated at editor time and used to generate the network id at runtime.
/// This is needed because finding all objects of type at runtime doesn't have a guaranteed order.
///
public int sceneNetworkId;
diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs
index 20aab53..06cc374 100644
--- a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs
+++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetManager.cs
@@ -51,6 +51,7 @@ namespace VelNet
ObjectSync,
TakeOwnership,
Instantiate,
+ InstantiateWithTransform,
Destroy,
DeleteSceneObjects,
Custom
@@ -1089,6 +1090,7 @@ namespace VelNet
Debug.LogError("Joining room before logging in.", instance);
return;
}
+
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
@@ -1235,36 +1237,15 @@ namespace VelNet
/// The NetworkObject for the instantiated object.
public static NetworkObject NetworkInstantiate(string prefabName)
{
- VelNetPlayer localPlayer = LocalPlayer;
- NetworkObject prefab = instance.prefabs.Find(p => p.name == prefabName);
- if (prefab == null)
- {
- VelNetLogger.Error("Couldn't find a prefab with that name: " + prefabName + "\nMake sure to add the prefab to list of prefabs in VelNetManager");
- return null;
- }
-
- string networkId = localPlayer.userid + "-" + localPlayer.lastObjectId++;
+ VelNetPlayer owner = LocalPlayer;
+ string networkId = AllocateNetworkId();
if (instance.objects.ContainsKey(networkId))
{
VelNetLogger.Error("Can't instantiate object. Obj with that network ID was already instantiated.", instance.objects[networkId]);
return null;
}
- NetworkObject newObject = Instantiate(prefab);
- newObject.networkId = networkId;
- newObject.prefabName = prefabName;
- newObject.owner = localPlayer;
- try
- {
- newObject.OwnershipChanged?.Invoke(localPlayer);
- }
- catch (Exception e)
- {
- VelNetLogger.Error("Error in event handling.\n" + e);
- }
-
- instance.objects.Add(newObject.networkId, newObject);
-
+ NetworkObject newObject = ActuallyInstantiate(networkId, prefabName, owner);
// only sent to others, as I already instantiated this. Nice that it happens immediately.
using MemoryStream mem = new MemoryStream();
@@ -1277,10 +1258,54 @@ namespace VelNet
return newObject;
}
- public static void SomebodyInstantiatedNetworkObject(string networkId, string prefabName, VelNetPlayer owner)
+ ///
+ /// Instantiates a prefab for all players at a specific location
+ ///
+ /// This prefab *must* by added to the list of prefabs in the scene's VelNetManager for all players.
+ ///
+ ///
+ /// The NetworkObject for the instantiated object.
+ public static NetworkObject NetworkInstantiate(string prefabName, Vector3 position, Quaternion rotation)
+ {
+ VelNetPlayer owner = LocalPlayer;
+ string networkId = AllocateNetworkId();
+ if (instance.objects.ContainsKey(networkId))
+ {
+ VelNetLogger.Error("Can't instantiate object. Obj with that network ID was already instantiated.", instance.objects[networkId]);
+ return null;
+ }
+
+ NetworkObject newObject = ActuallyInstantiate(networkId, prefabName, owner, position, rotation);
+
+ // only sent to others, as I already instantiated this. Nice that it happens immediately.
+ using MemoryStream mem = new MemoryStream();
+ using BinaryWriter writer = new BinaryWriter(mem);
+ writer.Write((byte)MessageType.InstantiateWithTransform);
+ writer.Write(newObject.networkId);
+ writer.Write(prefabName);
+ writer.Write(position);
+ writer.Write(rotation);
+ SendToRoom(mem.ToArray(), include_self: false, reliable: true);
+
+ return newObject;
+ }
+
+ ///
+ /// This happens locally on all clients
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static NetworkObject ActuallyInstantiate(string networkId, string prefabName, VelNetPlayer owner)
{
NetworkObject prefab = instance.prefabs.Find(p => p.name == prefabName);
- if (prefab == null) return;
+ if (prefab == null)
+ {
+ VelNetLogger.Error("Couldn't find a prefab with that name: " + prefabName + "\nMake sure to add the prefab to list of prefabs in VelNetManager");
+ return null;
+ }
+
NetworkObject newObject = Instantiate(prefab);
newObject.networkId = networkId;
newObject.prefabName = prefabName;
@@ -1295,6 +1320,42 @@ namespace VelNet
}
instance.objects.Add(newObject.networkId, newObject);
+ return newObject;
+ }
+
+
+ internal static NetworkObject ActuallyInstantiate(string networkId, string prefabName, VelNetPlayer owner, Vector3 position, Quaternion rotation)
+ {
+ NetworkObject prefab = instance.prefabs.Find(p => p.name == prefabName);
+ if (prefab == null)
+ {
+ VelNetLogger.Error("Couldn't find a prefab with that name: " + prefabName + "\nMake sure to add the prefab to list of prefabs in VelNetManager");
+ return null;
+ }
+
+ NetworkObject newObject = Instantiate(prefab, position, rotation);
+ newObject.instantiatedWithTransform = true;
+ newObject.initialPosition = position;
+ newObject.initialRotation = rotation;
+ newObject.networkId = networkId;
+ newObject.prefabName = prefabName;
+ newObject.owner = owner;
+ try
+ {
+ newObject.OwnershipChanged?.Invoke(owner);
+ }
+ catch (Exception e)
+ {
+ VelNetLogger.Error("Error in event handling.\n" + e);
+ }
+
+ instance.objects.Add(newObject.networkId, newObject);
+ return newObject;
+ }
+
+ private static string AllocateNetworkId()
+ {
+ return LocalPlayer.userid + "-" + LocalPlayer.lastObjectId++;
}
public static void NetworkDestroy(NetworkObject obj)
diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs
index 6480347..de993a8 100644
--- a/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs
+++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/VelNetPlayer.cs
@@ -18,7 +18,7 @@ namespace VelNet
private VelNetManager manager;
///
- /// For instantiation
+ /// For instantiation. This is not synced across the network
///
internal int lastObjectId;
@@ -41,12 +41,27 @@ namespace VelNet
{
if (kvp.Value.owner == this && kvp.Value.prefabName != "")
{
- using MemoryStream mem = new MemoryStream();
- using BinaryWriter writer = new BinaryWriter(mem);
- writer.Write((byte)VelNetManager.MessageType.Instantiate);
- writer.Write(kvp.Value.networkId);
- writer.Write(kvp.Value.prefabName);
- VelNetManager.SendToRoom(mem.ToArray(), false, true);
+ if (kvp.Value.instantiatedWithTransform)
+ {
+ using MemoryStream mem = new MemoryStream();
+ using BinaryWriter writer = new BinaryWriter(mem);
+ writer.Write((byte)VelNetManager.MessageType.InstantiateWithTransform);
+ writer.Write(kvp.Value.networkId);
+ writer.Write(kvp.Value.prefabName);
+ writer.Write(kvp.Value.initialPosition);
+ writer.Write(kvp.Value.initialRotation);
+ VelNetManager.SendToRoom(mem.ToArray(), false, true);
+ }
+ else
+ {
+ using MemoryStream mem = new MemoryStream();
+ using BinaryWriter writer = new BinaryWriter(mem);
+ writer.Write((byte)VelNetManager.MessageType.Instantiate);
+ writer.Write(kvp.Value.networkId);
+ writer.Write(kvp.Value.prefabName);
+ VelNetManager.SendToRoom(mem.ToArray(), false, true);
+ }
+
}
}
@@ -75,12 +90,12 @@ namespace VelNet
//individual message parameters separated by comma
VelNetManager.MessageType messageType = (VelNetManager.MessageType)reader.ReadByte();
- if(messageType == VelNetManager.MessageType.Custom)
+ if (messageType == VelNetManager.MessageType.Custom)
{
// Custom packets. These are global data that can be sent from anywhere.
// Any script can subscribe to the callback to receive the message data.
// todo: strange hack that any player can handle the custom message, which then simply calls velnetmanager.
-
+
int len = reader.ReadInt32();
try
{
@@ -90,6 +105,7 @@ namespace VelNet
{
VelNetLogger.Error(e.ToString());
}
+
return;
}
@@ -103,7 +119,7 @@ namespace VelNet
{
// sync update for an object "I" may own
// "I" being the person sending
- case VelNetManager.MessageType.ObjectSync:
+ case VelNetManager.MessageType.ObjectSync:
{
string objectKey = reader.ReadString();
byte componentIdx = reader.ReadByte();
@@ -113,7 +129,7 @@ namespace VelNet
{
bool isRpc = (componentIdx & 1) == 1;
componentIdx = (byte)(componentIdx >> 1);
-
+
// rpcs can be sent by non-owners
if (isRpc || manager.objects[objectKey].owner == this)
{
@@ -151,7 +167,22 @@ namespace VelNet
break; //we already have this one, ignore
}
- VelNetManager.SomebodyInstantiatedNetworkObject(networkId, prefabName, this);
+ VelNetManager.ActuallyInstantiate(networkId, prefabName, this);
+
+ break;
+ }
+ case VelNetManager.MessageType.InstantiateWithTransform: // I'm trying to instantiate an object
+ {
+ string networkId = reader.ReadString();
+ string prefabName = reader.ReadString();
+ Vector3 position = reader.ReadVector3();
+ Quaternion rotation = reader.ReadQuaternion();
+ if (manager.objects.ContainsKey(networkId))
+ {
+ break; //we already have this one, ignore
+ }
+
+ VelNetManager.ActuallyInstantiate(networkId, prefabName, this, position, rotation);
break;
}
@@ -170,7 +201,7 @@ namespace VelNet
break;
}
-
+
default:
throw new ArgumentOutOfRangeException();
}
diff --git a/TestVelGameServer/Packages/VelNetUnity/package.json b/TestVelGameServer/Packages/VelNetUnity/package.json
index 9f11729..7f81eb0 100644
--- a/TestVelGameServer/Packages/VelNetUnity/package.json
+++ b/TestVelGameServer/Packages/VelNetUnity/package.json
@@ -1,7 +1,7 @@
{
"name": "edu.uga.engr.vel.velnet",
"displayName": "VelNet",
- "version": "1.1.7",
+ "version": "1.1.8",
"unity": "2019.1",
"description": "A custom networking library for Unity.",
"keywords": [
@@ -35,4 +35,4 @@
"path": "Samples~/DissonanceExample"
}
]
-}
\ No newline at end of file
+}