Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a7159f4
feat: Network Tick System early prototype
jeffreyrainy Feb 26, 2021
7aad8c6
feat: Registering the tick system with the update loop system, dispos…
jeffreyrainy Feb 26, 2021
a983537
feat: Network Tick System PR comments
jeffreyrainy Feb 26, 2021
86b543d
fix: PR comments on comments
jeffreyrainy Feb 26, 2021
e78da7d
fix: last comments on PR
jeffreyrainy Feb 26, 2021
3632b94
fix: no singletons, extra doc
jeffreyrainy Feb 26, 2021
77630e8
feat: initial SyncTransform
jeffreyrainy Jan 19, 2021
198fc18
feat: prototype SyncTransform, using netvars and local extrapolation
jeffreyrainy Jan 20, 2021
7cb53a2
feat: SyncTransform, using FixedUpdate
jeffreyrainy Jan 21, 2021
f3e79bd
Changing NetworkedVar API to require tick number
jeffreyrainy Jan 27, 2021
dcf05ab
feat: netvar remember the tick they were set and received
jeffreyrainy Jan 29, 2021
1a289d6
writing srcTick and sndTick (still requires debugging)
jeffreyrainy Feb 4, 2021
8493a60
Reading the sndTick into the NetVar, which locally becomes the srcTick
jeffreyrainy Feb 4, 2021
7305720
feat: synced netvars, first prototype working
jeffreyrainy Feb 9, 2021
bf949b3
Comments, some cleanup
jeffreyrainy Feb 10, 2021
58dbdc0
Move of remote tick write, to allow keeping the INetworkedVar clean
jeffreyrainy Feb 10, 2021
be8be7a
Removing unneeded extras
jeffreyrainy Feb 10, 2021
b2f022b
Removing the tick on the initial netvars creation path
jeffreyrainy Feb 10, 2021
718b770
more cleanup
jeffreyrainy Feb 10, 2021
3f8c019
using interpolating in synctransform
jeffreyrainy Feb 11, 2021
16e16a8
removing read and write of ticks on path where it doesn't apply
jeffreyrainy Feb 15, 2021
8a681d5
new FileLogger API
jeffreyrainy Feb 15, 2021
676e888
fix: cleanup before PR
jeffreyrainy Feb 15, 2021
68ffeeb
placeholder for tick wrap-around
jeffreyrainy Feb 15, 2021
e8807f0
Removing the temporary/experimental SyncTransform.cs
jeffreyrainy Feb 15, 2021
173f141
fix: prevent tick update mid-frame
jeffreyrainy Feb 19, 2021
4ff1507
fix: moving the placeholder TickSystem more clearly out
jeffreyrainy Feb 24, 2021
3fcbbc2
PR comments
jeffreyrainy Feb 25, 2021
8a985d5
fix: bug fix for remote tick, when absent. Also removes commented code
jeffreyrainy Feb 25, 2021
b135574
fix: small fix to testproject
jeffreyrainy Feb 25, 2021
a069efa
fix: using the real NetworkTickSystem, instead of a placeholder one
jeffreyrainy Feb 26, 2021
7f1678c
fix: adpating to tick system changes
jeffreyrainy Feb 26, 2021
58e2ecc
add manual tests
0xFA11 Feb 26, 2021
022b69b
rename assembly definition
0xFA11 Feb 26, 2021
7947b2e
move manual tests assembly definition outside tests folder
0xFA11 Feb 26, 2021
30c1af7
move manual tests asmdef into testproject instead of mlapi, rename ma…
0xFA11 Feb 26, 2021
50a873a
Merge branch 'develop' into feature/manual-tests
0xFA11 Feb 26, 2021
50aaef8
remove MLAPI.ManualTests namespace
0xFA11 Feb 26, 2021
9bdbece
Merge remote-tracking branch 'origin/feature/manual-tests' into featu…
jeffreyrainy Feb 26, 2021
dd6b817
test: Adding manual tests for SyncNetVars
jeffreyrainy Feb 26, 2021
279d5f2
Merge branch 'develop' into feature/syncnetvars
jeffreyrainy Feb 26, 2021
ad7aa3f
Merge remote-tracking branch 'origin/develop' into feature/syncnetvars
jeffreyrainy Feb 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkedBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,11 @@ public bool HasNetworkedObject
internal bool networkedStartInvoked = false;
internal bool internalNetworkedStartInvoked = false;
/// <summary>
/// Stores the network tick at the NetworkedBehaviourUpdate time
/// This allows sending NetworkedVars not more often than once per network tick, regardless of the update rate
/// </summary>
public static ushort currentTick { get; private set; }
/// <summary>
/// Gets called when message handlers are ready to be registered and the networking is setup
/// </summary>
public virtual void NetworkStart()
Expand Down Expand Up @@ -521,6 +526,14 @@ internal void InitializeVars()

internal static void NetworkedBehaviourUpdate()
{
// Don't NetworkedBehaviourUpdate more than once per network tick
ushort tick = NetworkingManager.Singleton.networkTickSystem.GetTick();
if (tick == currentTick)
{
return;
}
currentTick = tick;

#if DEVELOPMENT_BUILD || UNITY_EDITOR
s_NetworkedBehaviourUpdate.Begin();
#endif
Expand Down Expand Up @@ -574,7 +587,6 @@ internal static void NetworkedBehaviourUpdate()
}
}
}

}
finally
{
Expand Down Expand Up @@ -615,8 +627,8 @@ internal void VarUpdate(ulong clientId)

private void NetworkedVarUpdate(ulong clientId)
{
if (!CouldHaveDirtyNetworkedVars())
return;
if (!CouldHaveDirtyNetworkedVars())
return;

for (int j = 0; j < channelMappedNetworkedVarIndexes.Count; j++)
{
Expand All @@ -627,6 +639,10 @@ private void NetworkedVarUpdate(ulong clientId)
writer.WriteUInt64Packed(NetworkId);
writer.WriteUInt16Packed(NetworkedObject.GetOrderIndex(this));

// Write the current tick frame
// todo: this is currently done per channel, per tick. The snapshot system might improve on this
writer.WriteUInt16Packed(currentTick);

bool writtenAny = false;
for (int k = 0; k < networkedVarFields.Count; k++)
{
Expand Down Expand Up @@ -716,6 +732,9 @@ internal static void HandleNetworkedVarDeltas(List<INetworkedVar> networkedVarLi
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
// read the remote network tick at which this variable was written.
ushort remoteTick = reader.ReadUInt16Packed();

for (int i = 0; i < networkedVarList.Count; i++)
{
ushort varSize = 0;
Expand Down Expand Up @@ -766,10 +785,15 @@ internal static void HandleNetworkedVarDeltas(List<INetworkedVar> networkedVarLi
}
}

// read the local network tick at which this variable was written.
// if this var was updated from our machine, this local tick will be locally valid
ushort localTick = reader.ReadUInt16Packed();

long readStartPos = stream.Position;

networkedVarList[i].ReadDelta(stream, IsServer);
networkedVarList[i].ReadDelta(stream, IsServer, localTick, remoteTick);
PerformanceDataManager.Increment(ProfilerConstants.NumberNetworkVarsReceived);

ProfilerStatManager.networkVarsRcvd.Record();

if (NetworkingManager.Singleton.NetworkConfig.EnsureNetworkedVarLengthSafety)
Expand Down Expand Up @@ -836,8 +860,9 @@ internal static void HandleNetworkedVarUpdate(List<INetworkedVar> networkedVarLi

long readStartPos = stream.Position;

networkedVarList[i].ReadField(stream);
networkedVarList[i].ReadField(stream, NetworkTickSystem.k_NoTick, NetworkTickSystem.k_NoTick);
PerformanceDataManager.Increment(ProfilerConstants.NumberNetworkVarsReceived);

ProfilerStatManager.networkVarsRcvd.Record();

if (NetworkingManager.Singleton.NetworkConfig.EnsureNetworkedVarLengthSafety)
Expand Down Expand Up @@ -934,7 +959,7 @@ internal static void SetNetworkedVarData(List<INetworkedVar> networkedVarList, S

long readStartPos = stream.Position;

networkedVarList[j].ReadField(stream);
networkedVarList[j].ReadField(stream, NetworkTickSystem.k_NoTick, NetworkTickSystem.k_NoTick);

if (NetworkingManager.Singleton.NetworkConfig.EnsureNetworkedVarLengthSafety)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public Channel GetChannel()
}

/// <inheritdoc />
public void ReadDelta(Stream stream, bool keepDirtyDelta)
public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
Expand Down Expand Up @@ -239,7 +239,7 @@ public void ReadDelta(Stream stream, bool keepDirtyDelta)
}

/// <inheritdoc />
public void ReadField(Stream stream)
public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public void WriteField(Stream stream)
}

/// <inheritdoc />
public void ReadField(Stream stream)
public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
Expand All @@ -217,7 +217,7 @@ public void ReadField(Stream stream)
}

/// <inheritdoc />
public void ReadDelta(Stream stream, bool keepDirtyDelta)
public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public void WriteField(Stream stream)
}

/// <inheritdoc />
public void ReadField(Stream stream)
public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
Expand All @@ -203,7 +203,7 @@ public void ReadField(Stream stream)
}

/// <inheritdoc />
public void ReadDelta(Stream stream, bool keepDirtyDelta)
public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
{
using (PooledBitReader reader = PooledBitReader.Get(stream))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ public interface INetworkedVar
/// Reads the complete state from the reader and applies it
/// </summary>
/// <param name="stream">The stream to read the state from</param>
void ReadField(Stream stream);
/// <param name="localTick">The local network tick at which this var was written, on the machine it was written </param>
/// <param name="remoteTick">The remote network tick at which this var was sent by the host </param>
void ReadField(Stream stream, ushort localTick, ushort remoteTick);
/// <summary>
/// Reads delta from the reader and applies them to the internal value
/// </summary>
/// <param name="stream">The stream to read the delta from</param>
/// <param name="keepDirtyDelta">Whether or not the delta should be kept as dirty or consumed</param>
void ReadDelta(Stream stream, bool keepDirtyDelta);
/// <param name="localTick">The local network tick at which this var was written, on the machine it was written </param>
/// <param name="remoteTick">The remote network tick at which this var was sent by the host </param>
void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick);
Comment on lines -51 to +61
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you think this PR introduces a breaking change, we should also call that out to be more cautious I think.

/// <summary>
/// Sets NetworkedBehaviour the container belongs to.
/// </summary>
Expand Down
46 changes: 34 additions & 12 deletions com.unity.multiplayer.mlapi/Runtime/NetworkedVar/NetworkedVar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using UnityEngine;
using System.IO;
using System;
using MLAPI.Logging;
using MLAPI.Serialization.Pooled;
using MLAPI.Transports;

Expand All @@ -22,9 +23,13 @@ public class NetworkedVar<T> : INetworkedVar
/// </summary>
public readonly NetworkedVarSettings Settings = new NetworkedVarSettings();
/// <summary>
/// Gets the last time the variable was synced
/// The last time the variable was written to locally
/// </summary>
public float LastSyncedTime { get; internal set; }
public ushort LocalTick { get; internal set; }
/// <summary>
/// The last time the variable was written to remotely. Uses the remote timescale
/// </summary>
public ushort RemoteTick { get; internal set; }
/// <summary>
/// Delegate type for value changed event
/// </summary>
Expand Down Expand Up @@ -89,6 +94,10 @@ public T Value
{
if (!EqualityComparer<T>.Default.Equals(InternalValue, value))
{
// Setter is assumed to be called locally, by game code.
// When used by the host, it is its responsibility to set the RemoteTick
RemoteTick = NetworkTickSystem.k_NoTick;

isDirty = true;
T previousValue = InternalValue;
InternalValue = value;
Expand All @@ -102,17 +111,12 @@ public T Value
public void ResetDirty()
{
isDirty = false;
LastSyncedTime = NetworkingManager.Singleton.NetworkTime;
}

/// <inheritdoc />
public bool IsDirty()
{
if (!isDirty) return false;
if (Settings.SendTickrate == 0) return true;
if (Settings.SendTickrate < 0) return false;
if (NetworkingManager.Singleton.NetworkTime - LastSyncedTime >= (1f / Settings.SendTickrate)) return true;
return false;
return isDirty;
}

/// <inheritdoc />
Expand All @@ -139,7 +143,18 @@ public bool CanClientRead(ulong clientId)
/// Writes the variable to the writer
/// </summary>
/// <param name="stream">The stream to write the value to</param>
public void WriteDelta(Stream stream) => WriteField(stream); //The NetworkedVar is built for simple data types and has no delta.
public void WriteDelta(Stream stream)
{
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
{
// write the network tick at which this NetworkedVar was modified remotely
// this will allow lag-compensation
// todo: this is currently only done on delta updates. Consider whether it should be done in WriteField
writer.WriteUInt16Packed(RemoteTick);
}

WriteField(stream);
}

/// <inheritdoc />
public bool CanClientWrite(ulong clientId)
Expand Down Expand Up @@ -167,8 +182,13 @@ public bool CanClientWrite(ulong clientId)
/// </summary>
/// <param name="stream">The stream to read the value from</param>
/// <param name="keepDirtyDelta">Whether or not the container should keep the dirty delta, or mark the delta as consumed</param>
public void ReadDelta(Stream stream, bool keepDirtyDelta)
public void ReadDelta(Stream stream, bool keepDirtyDelta, ushort localTick, ushort remoteTick)
{
// todo: This allows the host-returned value to be set back to an old value
// this will need to be adjusted to check if we're have a most recent value
LocalTick = localTick;
RemoteTick = remoteTick;

using (PooledBitReader reader = PooledBitReader.Get(stream))
{
T previousValue = InternalValue;
Expand All @@ -188,14 +208,16 @@ public void SetNetworkedBehaviour(NetworkedBehaviour behaviour)
}

/// <inheritdoc />
public void ReadField(Stream stream)
public void ReadField(Stream stream, ushort localTick, ushort remoteTick)
{
ReadDelta(stream, false);
ReadDelta(stream, false, localTick, remoteTick);
}

/// <inheritdoc />
public void WriteField(Stream stream)
{
// Store the local tick at which this NetworkedVar was modified
LocalTick = NetworkedBehaviour.currentTick;
using (PooledBitWriter writer = PooledBitWriter.Get(stream))
{
writer.WriteObjectPacked(InternalValue); //BOX
Expand Down
15 changes: 14 additions & 1 deletion testproject/Assets/Prefabs/Cube.prefab
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ GameObject:
- component: {fileID: -745482209883575862}
- component: {fileID: -7468455824255952951}
- component: {fileID: -4978466230159947418}
- component: {fileID: 2690316626396496521}
m_Layer: 0
m_Name: Cube
m_TagString: Target
Expand Down Expand Up @@ -170,7 +171,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3e34656ebae784afca7d1f7f6dc18580, type: 3}
m_Name:
m_EditorClassIdentifier:
range: 10
m_Range: 10
--- !u!120 &-745482209883575862
LineRenderer:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -328,3 +329,15 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9548116c10df1486ea12b7329b77c5cf, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &2690316626396496521
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8685790303553767886}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 962d0654df408407d8055453c9020f2b, type: 3}
m_Name:
m_EditorClassIdentifier:
Comment on lines +332 to +343
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeffreyrainy — I think we probably shouldn't have merged this change (this is ManualNetworkedVarTest component being attached to Cube.prefab here which is not in testproject on develop branch)

I'll revert this change in one of my PRs next week.

11 changes: 0 additions & 11 deletions testproject/Assets/Scripts/SyncTransform.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using MLAPI.Logging;
using MLAPI.NetworkedVar;
using UnityEngine;

Expand Down Expand Up @@ -50,7 +49,6 @@ void SyncPosChanged(Vector3 before, Vector3 after)
{
gameObject.transform.position = after;
}
//Debug.Log("[1] received position from " + before + " to " + after);
}
}

Expand All @@ -68,7 +66,6 @@ void SyncRotChanged(Quaternion before, Quaternion after)
{
gameObject.transform.rotation = after;
}
//Debug.Log("[2] received rotation from " + before + " to " + after);
}
}

Expand Down Expand Up @@ -118,10 +115,6 @@ void FixedUpdate()
{
gameObject.transform.position = m_PosStore[1];
}

var after = gameObject.transform.position;

//Debug.Log("[3] Updated position from " + before + " to " + after);
}

if (m_RotTimes[0] >= 0.0 && m_RotTimes[1] >= 0.0)
Expand All @@ -142,10 +135,6 @@ void FixedUpdate()
{
gameObject.transform.rotation = m_RotStore[1];
}

var after = gameObject.transform.rotation;

//Debug.Log("[4] Updated rotation from " + before + " to " + after);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion testproject/Assets/Scripts/Testing.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading