598 lines
14 KiB
C#
598 lines
14 KiB
C#
using System;
|
|
using System.IO;
|
|
using Photon.Pun;
|
|
using UnityEngine;
|
|
|
|
namespace Smooth
|
|
{
|
|
public class NetworkStatePUN2
|
|
{
|
|
public SmoothSyncPUN2 smoothSync;
|
|
|
|
public StatePUN2 state = new StatePUN2();
|
|
|
|
private byte positionMask = 1;
|
|
|
|
private byte rotationMask = 2;
|
|
|
|
private byte scaleMask = 4;
|
|
|
|
private byte velocityMask = 8;
|
|
|
|
private byte angularVelocityMask = 16;
|
|
|
|
private byte atPositionalRestMask = 64;
|
|
|
|
private byte atRotationalRestMask = 128;
|
|
|
|
public NetworkStatePUN2()
|
|
{
|
|
}
|
|
|
|
public NetworkStatePUN2(SmoothSyncPUN2 smoothSyncScript)
|
|
{
|
|
smoothSync = smoothSyncScript;
|
|
state.copyFromSmoothSync(smoothSyncScript);
|
|
}
|
|
|
|
public void copyFromSmoothSync(SmoothSyncPUN2 smoothSyncScript)
|
|
{
|
|
smoothSync = smoothSyncScript;
|
|
state.copyFromSmoothSync(smoothSyncScript);
|
|
}
|
|
|
|
public void Serialize(BinaryWriter writer)
|
|
{
|
|
bool sendPosition = smoothSync.sendPosition;
|
|
bool sendRotation = smoothSync.sendRotation;
|
|
bool sendScale = smoothSync.sendScale;
|
|
bool sendVelocity = smoothSync.sendVelocity;
|
|
bool sendAngularVelocity = smoothSync.sendAngularVelocity;
|
|
bool sendAtPositionalRestMessage = smoothSync.sendAtPositionalRestMessage;
|
|
bool sendAtRotationalRestMessage = smoothSync.sendAtRotationalRestMessage;
|
|
if (sendPosition)
|
|
{
|
|
smoothSync.lastPositionWhenStateWasSent = state.position;
|
|
}
|
|
if (sendRotation)
|
|
{
|
|
smoothSync.lastRotationWhenStateWasSent = state.rotation;
|
|
}
|
|
if (sendScale)
|
|
{
|
|
smoothSync.lastScaleWhenStateWasSent = state.scale;
|
|
}
|
|
if (sendVelocity)
|
|
{
|
|
smoothSync.lastVelocityWhenStateWasSent = state.velocity;
|
|
}
|
|
if (sendAngularVelocity)
|
|
{
|
|
smoothSync.lastAngularVelocityWhenStateWasSent = state.angularVelocity;
|
|
}
|
|
writer.Write(encodeSyncInformation(sendPosition, sendRotation, sendScale, sendVelocity, sendAngularVelocity, sendAtPositionalRestMessage, sendAtRotationalRestMessage));
|
|
writer.Write(state.ownerTimestamp);
|
|
if (sendPosition)
|
|
{
|
|
if (smoothSync.isPositionCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXPosition)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.position.x));
|
|
}
|
|
if (smoothSync.isSyncingYPosition)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.position.y));
|
|
}
|
|
if (smoothSync.isSyncingZPosition)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.position.z));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXPosition)
|
|
{
|
|
writer.Write(state.position.x);
|
|
}
|
|
if (smoothSync.isSyncingYPosition)
|
|
{
|
|
writer.Write(state.position.y);
|
|
}
|
|
if (smoothSync.isSyncingZPosition)
|
|
{
|
|
writer.Write(state.position.z);
|
|
}
|
|
}
|
|
}
|
|
if (sendRotation)
|
|
{
|
|
Vector3 eulerAngles = state.rotation.eulerAngles;
|
|
if (smoothSync.isRotationCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXRotation)
|
|
{
|
|
writer.Write(HalfHelper.Compress(eulerAngles.x * (MathF.PI / 180f)));
|
|
}
|
|
if (smoothSync.isSyncingYRotation)
|
|
{
|
|
writer.Write(HalfHelper.Compress(eulerAngles.y * (MathF.PI / 180f)));
|
|
}
|
|
if (smoothSync.isSyncingZRotation)
|
|
{
|
|
writer.Write(HalfHelper.Compress(eulerAngles.z * (MathF.PI / 180f)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXRotation)
|
|
{
|
|
writer.Write(eulerAngles.x);
|
|
}
|
|
if (smoothSync.isSyncingYRotation)
|
|
{
|
|
writer.Write(eulerAngles.y);
|
|
}
|
|
if (smoothSync.isSyncingZRotation)
|
|
{
|
|
writer.Write(eulerAngles.z);
|
|
}
|
|
}
|
|
}
|
|
if (sendScale)
|
|
{
|
|
if (smoothSync.isScaleCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXScale)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.scale.x));
|
|
}
|
|
if (smoothSync.isSyncingYScale)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.scale.y));
|
|
}
|
|
if (smoothSync.isSyncingZScale)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.scale.z));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXScale)
|
|
{
|
|
writer.Write(state.scale.x);
|
|
}
|
|
if (smoothSync.isSyncingYScale)
|
|
{
|
|
writer.Write(state.scale.y);
|
|
}
|
|
if (smoothSync.isSyncingZScale)
|
|
{
|
|
writer.Write(state.scale.z);
|
|
}
|
|
}
|
|
}
|
|
if (sendVelocity)
|
|
{
|
|
if (smoothSync.isVelocityCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXVelocity)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.velocity.x));
|
|
}
|
|
if (smoothSync.isSyncingYVelocity)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.velocity.y));
|
|
}
|
|
if (smoothSync.isSyncingZVelocity)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.velocity.z));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXVelocity)
|
|
{
|
|
writer.Write(state.velocity.x);
|
|
}
|
|
if (smoothSync.isSyncingYVelocity)
|
|
{
|
|
writer.Write(state.velocity.y);
|
|
}
|
|
if (smoothSync.isSyncingZVelocity)
|
|
{
|
|
writer.Write(state.velocity.z);
|
|
}
|
|
}
|
|
}
|
|
if (sendAngularVelocity)
|
|
{
|
|
if (smoothSync.isAngularVelocityCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXAngularVelocity)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.angularVelocity.x * (MathF.PI / 180f)));
|
|
}
|
|
if (smoothSync.isSyncingYAngularVelocity)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.angularVelocity.y * (MathF.PI / 180f)));
|
|
}
|
|
if (smoothSync.isSyncingZAngularVelocity)
|
|
{
|
|
writer.Write(HalfHelper.Compress(state.angularVelocity.z * (MathF.PI / 180f)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXAngularVelocity)
|
|
{
|
|
writer.Write(state.angularVelocity.x);
|
|
}
|
|
if (smoothSync.isSyncingYAngularVelocity)
|
|
{
|
|
writer.Write(state.angularVelocity.y);
|
|
}
|
|
if (smoothSync.isSyncingZAngularVelocity)
|
|
{
|
|
writer.Write(state.angularVelocity.z);
|
|
}
|
|
}
|
|
}
|
|
if (smoothSync.isSmoothingAuthorityChanges)
|
|
{
|
|
writer.Write((byte)smoothSync.ownerChangeIndicator);
|
|
}
|
|
if (smoothSync.automaticallyResetTime)
|
|
{
|
|
writer.Write((byte)state.localTimeResetIndicator);
|
|
}
|
|
}
|
|
|
|
public void Deserialize(BinaryReader reader, SmoothSyncPUN2 smoothSync)
|
|
{
|
|
byte syncInformation = reader.ReadByte();
|
|
bool flag = shouldSyncPosition(syncInformation);
|
|
bool flag2 = shouldSyncRotation(syncInformation);
|
|
bool flag3 = shouldSyncScale(syncInformation);
|
|
bool flag4 = shouldSyncVelocity(syncInformation);
|
|
bool flag5 = shouldSyncAngularVelocity(syncInformation);
|
|
state.atPositionalRest = shouldBeAtPositionalRest(syncInformation);
|
|
state.atRotationalRest = shouldBeAtRotationalRest(syncInformation);
|
|
state.ownerTimestamp = reader.ReadSingle();
|
|
if (!smoothSync)
|
|
{
|
|
Debug.LogWarning("Could not find target for network state message.");
|
|
return;
|
|
}
|
|
if (PhotonNetwork.IsMasterClient && !smoothSync.photonView.IsMine)
|
|
{
|
|
state.serverShouldRelayPosition = flag;
|
|
state.serverShouldRelayRotation = flag2;
|
|
state.serverShouldRelayScale = flag3;
|
|
state.serverShouldRelayVelocity = flag4;
|
|
state.serverShouldRelayAngularVelocity = flag5;
|
|
}
|
|
state.receivedTimestamp = smoothSync.localTime;
|
|
if (smoothSync.receivedStatesCounter < PhotonNetwork.SerializationRate)
|
|
{
|
|
smoothSync.receivedStatesCounter++;
|
|
}
|
|
if (flag)
|
|
{
|
|
if (smoothSync.isPositionCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXPosition)
|
|
{
|
|
state.position.x = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
if (smoothSync.isSyncingYPosition)
|
|
{
|
|
state.position.y = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
if (smoothSync.isSyncingZPosition)
|
|
{
|
|
state.position.z = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXPosition)
|
|
{
|
|
state.position.x = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingYPosition)
|
|
{
|
|
state.position.y = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingZPosition)
|
|
{
|
|
state.position.z = reader.ReadSingle();
|
|
}
|
|
}
|
|
}
|
|
else if (smoothSync.stateCount > 0)
|
|
{
|
|
state.position = smoothSync.stateBuffer[0].position;
|
|
}
|
|
else
|
|
{
|
|
state.position = smoothSync.getPosition();
|
|
}
|
|
if (flag2)
|
|
{
|
|
state.reusableRotationVector = Vector3.zero;
|
|
if (smoothSync.isRotationCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXRotation)
|
|
{
|
|
state.reusableRotationVector.x = HalfHelper.Decompress(reader.ReadUInt16());
|
|
state.reusableRotationVector.x *= 57.29578f;
|
|
}
|
|
if (smoothSync.isSyncingYRotation)
|
|
{
|
|
state.reusableRotationVector.y = HalfHelper.Decompress(reader.ReadUInt16());
|
|
state.reusableRotationVector.y *= 57.29578f;
|
|
}
|
|
if (smoothSync.isSyncingZRotation)
|
|
{
|
|
state.reusableRotationVector.z = HalfHelper.Decompress(reader.ReadUInt16());
|
|
state.reusableRotationVector.z *= 57.29578f;
|
|
}
|
|
state.rotation = Quaternion.Euler(state.reusableRotationVector);
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXRotation)
|
|
{
|
|
state.reusableRotationVector.x = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingYRotation)
|
|
{
|
|
state.reusableRotationVector.y = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingZRotation)
|
|
{
|
|
state.reusableRotationVector.z = reader.ReadSingle();
|
|
}
|
|
state.rotation = Quaternion.Euler(state.reusableRotationVector);
|
|
}
|
|
}
|
|
else if (smoothSync.stateCount > 0)
|
|
{
|
|
state.rotation = smoothSync.stateBuffer[0].rotation;
|
|
}
|
|
else
|
|
{
|
|
state.rotation = smoothSync.getRotation();
|
|
}
|
|
if (flag3)
|
|
{
|
|
if (smoothSync.isScaleCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXScale)
|
|
{
|
|
state.scale.x = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
if (smoothSync.isSyncingYScale)
|
|
{
|
|
state.scale.y = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
if (smoothSync.isSyncingZScale)
|
|
{
|
|
state.scale.z = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXScale)
|
|
{
|
|
state.scale.x = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingYScale)
|
|
{
|
|
state.scale.y = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingZScale)
|
|
{
|
|
state.scale.z = reader.ReadSingle();
|
|
}
|
|
}
|
|
}
|
|
else if (smoothSync.stateCount > 0)
|
|
{
|
|
state.scale = smoothSync.stateBuffer[0].scale;
|
|
}
|
|
else
|
|
{
|
|
state.scale = smoothSync.getScale();
|
|
}
|
|
if (flag4)
|
|
{
|
|
if (smoothSync.isVelocityCompressed)
|
|
{
|
|
if (smoothSync.isSyncingXVelocity)
|
|
{
|
|
state.velocity.x = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
if (smoothSync.isSyncingYVelocity)
|
|
{
|
|
state.velocity.y = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
if (smoothSync.isSyncingZVelocity)
|
|
{
|
|
state.velocity.z = HalfHelper.Decompress(reader.ReadUInt16());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXVelocity)
|
|
{
|
|
state.velocity.x = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingYVelocity)
|
|
{
|
|
state.velocity.y = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingZVelocity)
|
|
{
|
|
state.velocity.z = reader.ReadSingle();
|
|
}
|
|
}
|
|
smoothSync.latestReceivedVelocity = state.velocity;
|
|
}
|
|
else
|
|
{
|
|
state.velocity = smoothSync.latestReceivedVelocity;
|
|
}
|
|
if (flag5)
|
|
{
|
|
if (smoothSync.isAngularVelocityCompressed)
|
|
{
|
|
state.reusableRotationVector = Vector3.zero;
|
|
if (smoothSync.isSyncingXAngularVelocity)
|
|
{
|
|
state.reusableRotationVector.x = HalfHelper.Decompress(reader.ReadUInt16());
|
|
state.reusableRotationVector.x *= 57.29578f;
|
|
}
|
|
if (smoothSync.isSyncingYAngularVelocity)
|
|
{
|
|
state.reusableRotationVector.y = HalfHelper.Decompress(reader.ReadUInt16());
|
|
state.reusableRotationVector.y *= 57.29578f;
|
|
}
|
|
if (smoothSync.isSyncingZAngularVelocity)
|
|
{
|
|
state.reusableRotationVector.z = HalfHelper.Decompress(reader.ReadUInt16());
|
|
state.reusableRotationVector.z *= 57.29578f;
|
|
}
|
|
state.angularVelocity = state.reusableRotationVector;
|
|
}
|
|
else
|
|
{
|
|
if (smoothSync.isSyncingXAngularVelocity)
|
|
{
|
|
state.angularVelocity.x = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingYAngularVelocity)
|
|
{
|
|
state.angularVelocity.y = reader.ReadSingle();
|
|
}
|
|
if (smoothSync.isSyncingZAngularVelocity)
|
|
{
|
|
state.angularVelocity.z = reader.ReadSingle();
|
|
}
|
|
}
|
|
smoothSync.latestReceivedAngularVelocity = state.angularVelocity;
|
|
}
|
|
else
|
|
{
|
|
state.angularVelocity = smoothSync.latestReceivedAngularVelocity;
|
|
}
|
|
if (smoothSync.isSmoothingAuthorityChanges)
|
|
{
|
|
smoothSync.ownerChangeIndicator = reader.ReadByte();
|
|
}
|
|
if (smoothSync.automaticallyResetTime)
|
|
{
|
|
state.localTimeResetIndicator = reader.ReadByte();
|
|
}
|
|
}
|
|
|
|
private byte encodeSyncInformation(bool sendPosition, bool sendRotation, bool sendScale, bool sendVelocity, bool sendAngularVelocity, bool atPositionalRest, bool atRotationalRest)
|
|
{
|
|
byte b = 0;
|
|
if (sendPosition)
|
|
{
|
|
b |= positionMask;
|
|
}
|
|
if (sendRotation)
|
|
{
|
|
b |= rotationMask;
|
|
}
|
|
if (sendScale)
|
|
{
|
|
b |= scaleMask;
|
|
}
|
|
if (sendVelocity)
|
|
{
|
|
b |= velocityMask;
|
|
}
|
|
if (sendAngularVelocity)
|
|
{
|
|
b |= angularVelocityMask;
|
|
}
|
|
if (atPositionalRest)
|
|
{
|
|
b |= atPositionalRestMask;
|
|
}
|
|
if (atRotationalRest)
|
|
{
|
|
b |= atRotationalRestMask;
|
|
}
|
|
return b;
|
|
}
|
|
|
|
private bool shouldSyncPosition(byte syncInformation)
|
|
{
|
|
if ((syncInformation & positionMask) == positionMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool shouldSyncRotation(byte syncInformation)
|
|
{
|
|
if ((syncInformation & rotationMask) == rotationMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool shouldSyncScale(byte syncInformation)
|
|
{
|
|
if ((syncInformation & scaleMask) == scaleMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool shouldSyncVelocity(byte syncInformation)
|
|
{
|
|
if ((syncInformation & velocityMask) == velocityMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool shouldSyncAngularVelocity(byte syncInformation)
|
|
{
|
|
if ((syncInformation & angularVelocityMask) == angularVelocityMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool shouldBeAtPositionalRest(byte syncInformation)
|
|
{
|
|
if ((syncInformation & atPositionalRestMask) == atPositionalRestMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool shouldBeAtRotationalRest(byte syncInformation)
|
|
{
|
|
if ((syncInformation & atRotationalRestMask) == atRotationalRestMask)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|