PredictedSyncData struct first step: same reads & writes

This commit is contained in:
mischa 2024-03-14 11:39:19 +08:00 committed by MrGadget
parent ed12063f49
commit 9497121c45
3 changed files with 89 additions and 11 deletions

View File

@ -755,11 +755,17 @@ public override void OnSerialize(NetworkWriter writer, bool initialState)
// FAST VERSION: this shows in profiler a lot, so cache EVERYTHING! // FAST VERSION: this shows in profiler a lot, so cache EVERYTHING!
tf.GetPositionAndRotation(out Vector3 position, out Quaternion rotation); // faster than tf.position + tf.rotation. server's rigidbody is on the same transform. tf.GetPositionAndRotation(out Vector3 position, out Quaternion rotation); // faster than tf.position + tf.rotation. server's rigidbody is on the same transform.
writer.WriteFloat(Time.deltaTime);
writer.WriteVector3(position); // simple but slow write:
writer.WriteQuaternion(rotation); // writer.WriteFloat(Time.deltaTime);
writer.WriteVector3(predictedRigidbody.velocity); // writer.WriteVector3(position);
writer.WriteVector3(predictedRigidbody.angularVelocity); // writer.WriteQuaternion(rotation);
// writer.WriteVector3(predictedRigidbody.velocity);
// writer.WriteVector3(predictedRigidbody.angularVelocity);
// performance optimization: write a whole struct at once via blittable:
PredictedSyncData data = new PredictedSyncData(Time.deltaTime, position, rotation, predictedRigidbody.velocity, predictedRigidbody.angularVelocity);
writer.WritePredictedSyncData(data);
} }
// read the server's state, compare with client state & correct if necessary. // read the server's state, compare with client state & correct if necessary.
@ -769,12 +775,20 @@ public override void OnDeserialize(NetworkReader reader, bool initialState)
// we want to know the time on the server when this was sent, which is remoteTimestamp. // we want to know the time on the server when this was sent, which is remoteTimestamp.
double timestamp = NetworkClient.connection.remoteTimeStamp; double timestamp = NetworkClient.connection.remoteTimeStamp;
// parse state // simple but slow read:
double serverDeltaTime = reader.ReadFloat(); // double serverDeltaTime = reader.ReadFloat();
Vector3 position = reader.ReadVector3(); // Vector3 position = reader.ReadVector3();
Quaternion rotation = reader.ReadQuaternion(); // Quaternion rotation = reader.ReadQuaternion();
Vector3 velocity = reader.ReadVector3(); // Vector3 velocity = reader.ReadVector3();
Vector3 angularVelocity = reader.ReadVector3(); // Vector3 angularVelocity = reader.ReadVector3();
// performance optimization: read a whole struct at once via blittable:
PredictedSyncData data = reader.ReadPredictedSyncData();
double serverDeltaTime = data.deltaTime;
Vector3 position = data.position;
Quaternion rotation = data.rotation;
Vector3 velocity = data.velocity;
Vector3 angularVelocity = data.angularVelocity;
// server sends state at the end of the frame. // server sends state at the end of the frame.
// parse and apply the server's delta time to our timestamp. // parse and apply the server's delta time to our timestamp.

View File

@ -0,0 +1,61 @@
// this struct exists only for OnDe/Serialize performance.
// instead of WriteVector3+Quaternion+Vector3+Vector3,
// we read & write the whole struct as blittable once.
//
// struct packing can cause odd results with blittable on different platforms,
// so this is usually not recommended!
//
// in this case however, we need to squeeze everything we can out of prediction
// to support low even devices / VR.
using System.Runtime.InteropServices;
using UnityEngine;
namespace Mirror
{
// struct packing
[StructLayout(LayoutKind.Sequential)] // explicitly force sequential
public struct PredictedSyncData
{
public float deltaTime; // 4 bytes (word aligned)
public Vector3 position; // 12 bytes (word aligned)
public Quaternion rotation; // 16 bytes (word aligned)
public Vector3 velocity; // 12 bytes (word aligned)
public Vector3 angularVelocity; // 12 bytes (word aligned)
// constructor for convenience
public PredictedSyncData(float deltaTime, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 angularVelocity)
{
this.deltaTime = deltaTime;
this.position = position;
this.rotation = rotation;
this.velocity = velocity;
this.angularVelocity = angularVelocity;
}
}
// NetworkReader/Writer extensions to write this struct
public static class PredictedSyncDataReadWrite
{
public static void WritePredictedSyncData(this NetworkWriter writer, PredictedSyncData data)
{
writer.WriteFloat(data.deltaTime);
writer.WriteVector3(data.position);
writer.WriteQuaternion(data.rotation);
writer.WriteVector3(data.velocity);
writer.WriteVector3(data.angularVelocity);
}
public static PredictedSyncData ReadPredictedSyncData(this NetworkReader reader)
{
return new PredictedSyncData
{
deltaTime = reader.ReadFloat(),
position = reader.ReadVector3(),
rotation = reader.ReadQuaternion(),
velocity = reader.ReadVector3(),
angularVelocity = reader.ReadVector3()
};
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f595f112a39e4634b670d56991b23823
timeCreated: 1710387026