diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj
index f020c769..09b91421 100644
--- a/QSB/QSB.csproj
+++ b/QSB/QSB.csproj
@@ -237,6 +237,7 @@
+
diff --git a/QSB/TransformSync/IntermediaryTransform.cs b/QSB/TransformSync/IntermediaryTransform.cs
new file mode 100644
index 00000000..2725adbc
--- /dev/null
+++ b/QSB/TransformSync/IntermediaryTransform.cs
@@ -0,0 +1,72 @@
+using QSB.SectorSync.WorldObjects;
+using UnityEngine;
+
+namespace QSB.TransformSync
+{
+ class IntermediaryTransform
+ {
+ private Transform _attachedTransform;
+ private QSBSector _referenceSector;
+
+ public IntermediaryTransform(Transform transform)
+ {
+ _attachedTransform = transform;
+ }
+ ///
+ /// Get the world position of this INVISIBLE transform.
+ ///
+ public Vector3 GetPosition()
+ => _attachedTransform.position;
+
+ ///
+ /// Set the world position of this INVISIBLE transform.
+ ///
+ public void SetPosition(Vector3 worldPos)
+ => _attachedTransform.position = worldPos;
+
+ ///
+ /// Get the world rotation of this INVISIBLE transform.
+ ///
+ public Quaternion GetRotation()
+ => _attachedTransform.rotation;
+
+ ///
+ /// Set the world rotation of this INVISIBLE transform.
+ ///
+ public void SetRotation(Quaternion worldRot)
+ => _attachedTransform.rotation = worldRot;
+
+ ///
+ /// Sets the reference sector - what sector this transform is syncing to.
+ ///
+ /// The new reference sector.
+ public void SetReferenceSector(QSBSector sector)
+ => _referenceSector = sector;
+
+ ///
+ /// Sets the position of the INVISIBLE transform to be correct, according to the reference sector and the position of the VISIBLE transform.
+ ///
+ /// The world position of the VISIBLE transform.
+ public void EncodePosition(Vector3 worldPosition)
+ => SetPosition(_referenceSector.Transform.InverseTransformPoint(worldPosition));
+
+ ///
+ /// Sets the rotation of the INVISIBLE transform to be correct, according to the reference sector and the rotation of the VISIBLE transform.
+ ///
+ /// The world rotation of the VISIBLE transform.
+ public void EncodeRotation(Quaternion worldRotation)
+ => SetRotation(_referenceSector.Transform.InverseTransformRotation(worldRotation));
+
+ ///
+ /// Gets what the VISIBLE transform's position should be, from the reference sector and the position of the INVISIBLE transform.
+ ///
+ public Vector3 GetTargetPosition()
+ => GetPosition();
+
+ ///
+ /// Gets what the VISIBLE transform's rotation should be, from the reference sector and the rotation of the INVISIBLE transform.
+ ///
+ public Quaternion GetTargetRotation()
+ => GetRotation();
+ }
+}
diff --git a/QSB/TransformSync/QSBNetworkTransform.cs b/QSB/TransformSync/QSBNetworkTransform.cs
index 87c9e693..f59c2e1b 100644
--- a/QSB/TransformSync/QSBNetworkTransform.cs
+++ b/QSB/TransformSync/QSBNetworkTransform.cs
@@ -35,6 +35,7 @@ namespace QSB.TransformSync
private float _previousDistance;
private Vector3 _positionSmoothVelocity;
private Quaternion _rotationSmoothVelocity;
+ private IntermediaryTransform _intermediaryTransform;
public virtual void Start()
{
@@ -47,6 +48,7 @@ namespace QSB.TransformSync
NetworkTransformList.Add(this);
DontDestroyOnLoad(gameObject);
+ _intermediaryTransform = new IntermediaryTransform(transform);
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
@@ -78,6 +80,10 @@ namespace QSB.TransformSync
public override void SerializeTransform(QNetworkWriter writer)
{
+ if (_intermediaryTransform == null)
+ {
+ _intermediaryTransform = new IntermediaryTransform(transform);
+ }
if (ReferenceSector != null)
{
writer.Write(ReferenceSector.ObjectId);
@@ -87,10 +93,12 @@ namespace QSB.TransformSync
writer.Write(-1);
}
- writer.Write(transform.position);
- SerializeRotation(writer, transform.rotation);
- _prevPosition = transform.position;
- _prevRotation = transform.rotation;
+ var worldPos = _intermediaryTransform.GetPosition();
+ var worldRot = _intermediaryTransform.GetRotation();
+ writer.Write(worldPos);
+ SerializeRotation(writer, worldRot);
+ _prevPosition = worldPos;
+ _prevRotation = worldRot;
}
public override void DeserializeTransform(QNetworkReader reader)
@@ -121,10 +129,10 @@ namespace QSB.TransformSync
return;
}
- transform.position = pos;
- transform.rotation = rot;
+ _intermediaryTransform.SetPosition(pos);
+ _intermediaryTransform.SetRotation(rot);
- if (transform.position == Vector3.zero)
+ if (_intermediaryTransform.GetPosition() == Vector3.zero)
{
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given position was {pos} at sector {sector?.Name}", MessageType.Warning);
}
@@ -162,23 +170,23 @@ namespace QSB.TransformSync
{
if (HasAuthority)
{
- transform.position = ReferenceSector.Transform.InverseTransformPoint(AttachedObject.transform.position);
- transform.rotation = ReferenceSector.Transform.InverseTransformRotation(AttachedObject.transform.rotation);
+ _intermediaryTransform.EncodePosition(AttachedObject.transform.position);
+ _intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
}
else
{
- var localToWorldPos = ReferenceSector.Transform.TransformPoint(transform.position);
- var localToWorldRot = ReferenceSector.Transform.TransformRotation(transform.rotation);
- AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, localToWorldPos);
- AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, localToWorldRot, ref _rotationSmoothVelocity, SmoothTime);
+ var targetPos = _intermediaryTransform.GetTargetPosition();
+ var targetRot = _intermediaryTransform.GetTargetRotation();
+ AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, targetPos);
+ AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
}
}
public override bool HasMoved()
{
- var displacementMagnitude = (transform.position - _prevPosition).magnitude;
+ var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
return displacementMagnitude > 1E-03f
- || Quaternion.Angle(transform.rotation, _prevRotation) > 1E-03f;
+ || Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f;
}
public void SetReferenceSector(QSBSector sector)
@@ -188,6 +196,7 @@ namespace QSB.TransformSync
return;
}
ReferenceSector = sector;
+ _intermediaryTransform.SetReferenceSector(sector);
if (AttachedObject == null)
{
DebugLog.ToConsole($"Warning - AttachedObject was null for {PlayerId}.{GetType().Name} when trying to set reference sector to {sector.Name}. Waiting until not null...", MessageType.Warning);
@@ -238,7 +247,7 @@ namespace QSB.TransformSync
return;
}
- Popcron.Gizmos.Cube(transform.position, transform.rotation, Vector3.one / 2, Color.red);
+ Popcron.Gizmos.Cube(_intermediaryTransform.GetTargetPosition(), _intermediaryTransform.GetTargetRotation(), Vector3.one / 2, Color.red);
var color = HasMoved() ? Color.green : Color.yellow;
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 2, color);
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceSector.Transform.position, Color.cyan);