added takeownership editor button, improved samples, add IPackState interface to serialization scripts

main
Anton Franzluebbers 2023-08-03 13:07:40 -04:00
parent 357d4a5dd8
commit 61444aee34
17 changed files with 360 additions and 41 deletions

View File

View File

@ -175,6 +175,11 @@ namespace VelNet
EditorGUI.EndDisabledGroup();
EditorGUILayout.Space();
if (EditorApplication.isPlaying && GUILayout.Button("Take ownership now."))
{
t.TakeOwnership();
}
if (GUILayout.Button("Find Network Components and add backreferences."))
{
NetworkComponent[] components = t.GetComponentsInChildren<NetworkComponent>();
@ -193,6 +198,8 @@ namespace VelNet
so.ApplyModifiedProperties();
}
// make the sceneNetworkId a new unique value
if (Application.isEditor && !Application.isPlaying && t.isSceneObject && t.sceneNetworkId == 0)
{

View File

@ -0,0 +1,8 @@
namespace VelNet
{
public interface IPackState
{
public byte[] PackState();
public void UnpackState(byte[] state);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ff05d1e7d5ce4aa7b8a57c15e3fe6f6d
timeCreated: 1690999043

View File

@ -4,7 +4,7 @@ using UnityEngine;
namespace VelNet
{
public abstract class NetworkSerializedObject : NetworkComponent
public abstract class NetworkSerializedObject : NetworkComponent, IPackState
{
[Tooltip("Send rate of this object. This caps out at the framerate of the game.")]
public float serializationRateHz = 30;
@ -67,5 +67,15 @@ namespace VelNet
protected abstract byte[] SendState();
protected abstract void ReceiveState(byte[] message);
public byte[] PackState()
{
return SendState();
}
public void UnpackState(byte[] state)
{
ReceiveState(state);
}
}
}

View File

@ -5,7 +5,7 @@ using UnityEngine;
namespace VelNet
{
public abstract class NetworkSerializedObjectStream : NetworkComponent
public abstract class NetworkSerializedObjectStream : NetworkComponent, IPackState
{
[Tooltip("Send rate of this object. This caps out at the framerate of the game.")]
public float serializationRateHz = 30;
@ -40,7 +40,8 @@ namespace VelNet
byte[] newBytes = mem.ToArray();
if (hybridOnChangeCompression)
{
if (Time.timeAsDouble - lastSendTime > slowSendInterval || !BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes))
if (Time.timeAsDouble - lastSendTime > slowSendInterval ||
!BinaryWriterExtensions.BytesSame(lastSentBytes, newBytes))
{
SendBytes(newBytes);
lastSendTime = Time.timeAsDouble;
@ -76,5 +77,21 @@ namespace VelNet
protected abstract void SendState(BinaryWriter binaryWriter);
protected abstract void ReceiveState(BinaryReader binaryReader);
public byte[] PackState()
{
using MemoryStream mem = new MemoryStream();
using BinaryWriter writer = new BinaryWriter(mem);
SendState(writer);
return mem.ToArray();
}
public void UnpackState(byte[] state)
{
using MemoryStream mem = new MemoryStream(state);
using BinaryReader reader = new BinaryReader(mem);
ReceiveState(reader);
}
}
}

View File

@ -135,7 +135,11 @@ namespace VelNet
public readonly Dictionary<string, List<int>> groups = new Dictionary<string, List<int>>();
private VelNetPlayer masterPlayer;
public static VelNetPlayer LocalPlayer => instance != null ? instance.players.Where(p => p.Value.isLocal).Select(p => p.Value).FirstOrDefault() : null;
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;
@ -309,7 +313,9 @@ namespace VelNet
if (autoLogin)
{
Login(
onlyConnectToSameVersion ? $"{Application.productName}_{Application.version}" : $"{Application.productName}",
onlyConnectToSameVersion
? $"{Application.productName}_{Application.version}"
: $"{Application.productName}",
Hash128.Compute(SystemInfo.deviceUniqueIdentifier).ToString()
);
}
@ -526,8 +532,10 @@ namespace VelNet
}
else
{
masterPlayer = players.Aggregate((p1, p2) => p1.Value.userid.CompareTo(p2.Value.userid) > 0 ? p1 : p2).Value;
VelNetLogger.Error("Got an invalid master client id from the server. Using fallback.");
masterPlayer = players.Aggregate((p1, p2) =>
p1.Value.userid.CompareTo(p2.Value.userid) > 0 ? p1 : p2).Value;
VelNetLogger.Error(
"Got an invalid master client id from the server. Using fallback.");
}
// no master player yet, add the scene objects
@ -536,7 +544,8 @@ namespace VelNet
{
if (sceneObjects[i].sceneNetworkId == 0)
{
VelNetLogger.Error("Scene Network ID is 0. Make sure to assign one first.", sceneObjects[i]);
VelNetLogger.Error("Scene Network ID is 0. Make sure to assign one first.",
sceneObjects[i]);
}
sceneObjects[i].networkId = -1 + "-" + sceneObjects[i].sceneNetworkId;
@ -553,7 +562,8 @@ namespace VelNet
if (objects.ContainsKey(sceneObjects[i].networkId))
{
VelNetLogger.Error($"Duplicate NetworkID: {sceneObjects[i].networkId} {sceneObjects[i].name} {objects[sceneObjects[i].networkId]}");
VelNetLogger.Error(
$"Duplicate NetworkID: {sceneObjects[i].networkId} {sceneObjects[i].name} {objects[sceneObjects[i].networkId]}");
}
else
{
@ -1123,7 +1133,8 @@ namespace VelNet
}
}
public static void SendCustomMessage(byte[] message, bool include_self = false, bool reliable = true, bool ordered = false)
public static void SendCustomMessage(byte[] message, bool include_self = false, bool reliable = true,
bool ordered = false)
{
using MemoryStream mem = new MemoryStream();
using BinaryWriter writer = new BinaryWriter(mem);
@ -1143,7 +1154,8 @@ namespace VelNet
SendToGroup(group, mem.ToArray(), reliable);
}
internal static bool SendToRoom(byte[] message, bool include_self = false, bool reliable = true, bool ordered = false)
internal static bool SendToRoom(byte[] message, bool include_self = false, bool reliable = true,
bool ordered = false)
{
byte sendType = (byte)MessageSendType.MESSAGE_OTHERS;
if (include_self && ordered) sendType = (byte)MessageSendType.MESSAGE_ALL_ORDERED;
@ -1230,6 +1242,16 @@ namespace VelNet
return NetworkInstantiate(prefabName);
}
public static NetworkObject NetworkInstantiate(NetworkObject prefab)
{
if (instance.prefabs.Contains(prefab))
{
return NetworkInstantiate(prefab.name);
}
throw new ArgumentException("Can't instantiate object that isn't added to the network manager.");
}
/// <summary>
/// Instantiates a prefab for all players.
/// </summary>
@ -1241,7 +1263,8 @@ namespace VelNet
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]);
VelNetLogger.Error("Can't instantiate object. Obj with that network ID was already instantiated.",
instance.objects[networkId]);
return null;
}
@ -1271,7 +1294,8 @@ namespace VelNet
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]);
VelNetLogger.Error("Can't instantiate object. Obj with that network ID was already instantiated.",
instance.objects[networkId]);
return null;
}
@ -1302,7 +1326,8 @@ namespace VelNet
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");
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;
}
@ -1324,12 +1349,14 @@ namespace VelNet
}
internal static NetworkObject ActuallyInstantiate(string networkId, string prefabName, VelNetPlayer owner, Vector3 position, Quaternion rotation)
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");
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;
}

View File

@ -0,0 +1,177 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &419466048389313172
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 419466048389313162}
- component: {fileID: 419466048389313163}
- component: {fileID: 419466048389313160}
- component: {fileID: 419466048389313161}
- component: {fileID: 419466048389313174}
- component: {fileID: 419466048389313175}
- component: {fileID: 5526065058146758772}
- component: {fileID: 7493820295801030223}
m_Layer: 0
m_Name: TestNetworkedGameObjectMoving
m_TagString: draggable
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &419466048389313162
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
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_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &419466048389313163
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &419466048389313160
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!65 &419466048389313161
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &419466048389313174
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5515094c5c544b6b8ed7fd51a86548d4, type: 3}
m_Name:
m_EditorClassIdentifier:
ownershipLocked: 0
networkId:
sceneNetworkId: 0
prefabName:
isSceneObject: 0
syncedComponents:
- {fileID: 7493820295801030223}
- {fileID: 419466048389313175}
--- !u!114 &419466048389313175
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3f1f9b0bbd93a484a987c51f1107ebe5, type: 3}
m_Name:
m_EditorClassIdentifier:
networkObject: {fileID: 419466048389313174}
serializationRateHz: 60
hybridOnChangeCompression: 1
position: 1
rotation: 1
scale: 0
useLocalTransform: 0
teleportDistance: 0
teleportAngle: 0
--- !u!54 &5526065058146758772
Rigidbody:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
serializedVersion: 2
m_Mass: 1
m_Drag: 1
m_AngularDrag: 1
m_UseGravity: 0
m_IsKinematic: 0
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!114 &7493820295801030223
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 419466048389313172}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 89cb4504498539945b9d89e5e0bc8c54, type: 3}
m_Name:
m_EditorClassIdentifier:
networkObject: {fileID: 419466048389313174}
serializationRateHz: 30
hybridOnChangeCompression: 1
impulseForce: 200
returningForce: 1

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ca24b76e2d421f7468d28a27a9858d29
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -750,6 +750,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
@ -2599,6 +2600,7 @@ MonoBehaviour:
prefabs:
- {fileID: 9102273340480352682, guid: e07dfcf3af0e6ad438df1df54cd960a5, type: 3}
- {fileID: 419466048389313174, guid: c0c7ee35b5be203468523c819c9da422, type: 3}
- {fileID: 419466048389313174, guid: ca24b76e2d421f7468d28a27a9858d29, type: 3}
sceneObjects: []
deletedSceneObjects: []
--- !u!114 &1099803618

View File

@ -10,11 +10,12 @@ namespace VelNet
{
private Renderer rend;
public Color color;
public NetworkObject spawnableObj;
protected void Start()
{
rend = GetComponent<MeshRenderer>();
if (IsMine)
{
color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
@ -35,7 +36,17 @@ namespace VelNet
if (Input.GetKeyDown(KeyCode.Space))
{
VelNetManager.NetworkInstantiate("TestNetworkedGameObject");
if (Input.GetKey(KeyCode.LeftShift))
{
for (int i = 0; i < 100; i++)
{
VelNetManager.NetworkInstantiate(spawnableObj);
}
}
else
{
VelNetManager.NetworkInstantiate(spawnableObj);
}
}
if (Input.GetKeyDown(KeyCode.BackQuote))

View File

@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using VelNet;
public class SyncedCustomObj : NetworkSerializedObjectStream
{
private Renderer rend;
private Rigidbody rb;
public float impulseForce = 1;
public float returningForce = 1;
private IEnumerator Start()
{
rend = GetComponent<Renderer>();
rb = GetComponent<Rigidbody>();
while (true)
{
if (IsMine)
{
rb.AddForce(new Vector3(
Random.Range(-1f, 1f) * impulseForce,
Random.Range(-1f, 1f) * impulseForce,
Random.Range(-1f, 1f) * impulseForce
));
}
yield return new WaitForSeconds(Random.Range(1f, 3f));
}
}
private void FixedUpdate()
{
if (IsMine)
{
// return to center
rb.velocity -= (transform.position).normalized * Time.fixedDeltaTime * returningForce;
}
}
protected override void SendState(BinaryWriter binaryWriter)
{
}
protected override void ReceiveState(BinaryReader binaryReader)
{
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89cb4504498539945b9d89e5e0bc8c54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,7 @@
{
"name": "edu.uga.engr.vel.velnet",
"displayName": "VelNet",
"version": "1.1.8",
"version": "1.1.9",
"unity": "2019.1",
"description": "A custom networking library for Unity.",
"keywords": [

View File

@ -1,9 +1,9 @@
{
"dependencies": {
"com.franzco.unityutilities": "https://github.com/AntonFranzluebbers/unityutilities.git",
"com.unity.collab-proxy": "1.17.7",
"com.unity.ide.rider": "3.0.17",
"com.unity.ide.visualstudio": "2.0.17",
"com.unity.collab-proxy": "2.0.3",
"com.unity.ide.rider": "3.0.20",
"com.unity.ide.visualstudio": "2.0.18",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.3.2",
"com.unity.textmeshpro": "3.0.6",

View File

@ -11,12 +11,10 @@
"hash": "330ff73d80febbf9b505dd0ebd86d370d12fc73d"
},
"com.unity.collab-proxy": {
"version": "1.17.7",
"version": "2.0.3",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.services.core": "1.0.1"
},
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
@ -27,7 +25,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "3.0.17",
"version": "3.0.20",
"depth": 0,
"source": "registry",
"dependencies": {
@ -36,7 +34,7 @@
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.17",
"version": "2.0.18",
"depth": 0,
"source": "registry",
"dependencies": {
@ -52,21 +50,12 @@
"url": "https://packages.unity.com"
},
"com.unity.nuget.newtonsoft-json": {
"version": "2.0.0",
"version": "3.1.0",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.services.core": {
"version": "1.0.1",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.3.2",
"depth": 0,
@ -109,7 +98,7 @@
}
},
"com.unity.xr.legacyinputhelpers": {
"version": "2.1.9",
"version": "2.1.10",
"depth": 1,
"source": "registry",
"dependencies": {

View File

@ -1,2 +1,2 @@
m_EditorVersion: 2021.3.1f1
m_EditorVersionWithRevision: 2021.3.1f1 (3b70a0754835)
m_EditorVersion: 2021.3.24f1
m_EditorVersionWithRevision: 2021.3.24f1 (cf10dcf7010d)