182 lines
5.1 KiB
C#
Raw Normal View History

2020-08-31 09:36:29 +01:00
using OWML.Common;
2020-11-03 21:33:48 +00:00
using QSB.Player;
using QSB.SectorSync.WorldObjects;
2020-08-31 09:36:29 +01:00
using QSB.Utility;
2020-12-14 19:23:24 +00:00
using System.Linq;
2020-08-31 09:36:29 +01:00
using UnityEngine;
namespace QSB.TransformSync
{
2020-12-02 21:29:53 +00:00
public abstract class TransformSync : PlayerSyncObject
{
public abstract bool IsReady { get; }
2020-12-03 08:28:05 +00:00
2020-12-02 21:29:53 +00:00
protected abstract Transform InitLocalTransform();
protected abstract Transform InitRemoteTransform();
public Transform SyncedTransform { get; private set; }
public QSBSector ReferenceSector { get; set; }
2021-03-09 19:45:00 +00:00
public SectorSync.SectorSync SectorSync { get; private set; }
2020-12-02 21:29:53 +00:00
private const float SmoothTime = 0.1f;
2021-02-19 13:23:14 +00:00
private const float DistanceLeeway = 5f;
2020-12-02 21:29:53 +00:00
private bool _isInitialized;
private Vector3 _positionSmoothVelocity;
private Quaternion _rotationSmoothVelocity;
private bool _isVisible;
2021-02-19 13:23:14 +00:00
private float _previousDistance;
2020-12-02 21:29:53 +00:00
2020-12-14 19:23:24 +00:00
protected override void Start()
2020-12-02 21:29:53 +00:00
{
2020-12-14 19:23:24 +00:00
base.Start();
2020-12-19 14:49:15 +00:00
var lowestBound = QSBPlayerManager.GetSyncObjects<PlayerTransformSync>()
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
2020-12-14 19:23:24 +00:00
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
2021-03-09 19:45:00 +00:00
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
2020-12-02 21:29:53 +00:00
DontDestroyOnLoad(gameObject);
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
}
2020-12-14 16:04:16 +00:00
protected override void OnDestroy()
2020-12-02 21:29:53 +00:00
{
2020-12-14 16:04:16 +00:00
base.OnDestroy();
2020-12-12 11:27:28 +00:00
if (!HasAuthority && SyncedTransform != null)
{
Destroy(SyncedTransform.gameObject);
}
2020-12-02 21:29:53 +00:00
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
2021-03-22 16:03:00 +00:00
if (SectorSync != null)
{
Destroy(SectorSync);
}
2020-12-02 21:29:53 +00:00
}
2020-12-14 21:20:53 +00:00
private void OnSceneLoaded(OWScene scene, bool isInUniverse) =>
_isInitialized = false;
2020-12-02 21:29:53 +00:00
2020-12-14 21:20:53 +00:00
protected void Init()
2020-12-02 21:29:53 +00:00
{
SyncedTransform = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
2021-03-09 19:45:00 +00:00
SetReferenceSector(SectorSync.GetClosestSector(SyncedTransform));
2020-12-02 21:29:53 +00:00
_isInitialized = true;
_isVisible = true;
}
2021-03-31 10:30:51 +01:00
public void OnRenderObject()
{
if (!QSBCore.HasWokenUp || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug || !IsReady)
{
return;
}
Popcron.Gizmos.Cube(SyncedTransform.position, SyncedTransform.rotation, Vector3.one / 2, Color.green);
Popcron.Gizmos.Cube(transform.position, transform.rotation, Vector3.one / 2, Color.red);
Popcron.Gizmos.Line(SyncedTransform.position, transform.position, Color.magenta);
Popcron.Gizmos.Cube(ReferenceSector.Position, ReferenceSector.Transform.rotation, Vector3.one, Color.cyan);
Popcron.Gizmos.Line(SyncedTransform.position, ReferenceSector.Position, Color.blue);
}
2020-12-14 21:41:56 +01:00
public void Update()
2020-12-02 21:29:53 +00:00
{
if (!_isInitialized && IsReady)
{
Init();
}
else if (_isInitialized && !IsReady)
{
_isInitialized = false;
return;
}
if (!_isInitialized)
{
return;
}
if (SyncedTransform == null)
{
DebugLog.ToConsole($"Warning - SyncedTransform {Player.PlayerId}.{GetType().Name} is null.", MessageType.Warning);
return;
}
UpdateTransform();
}
protected virtual void UpdateTransform()
{
2020-12-03 08:28:05 +00:00
if (HasAuthority) // If this script is attached to the client's own body on the client's side.
2020-12-02 21:29:53 +00:00
{
2020-12-23 22:43:05 +00:00
if (ReferenceSector == null || ReferenceSector.AttachedObject == null)
2020-12-02 21:29:53 +00:00
{
DebugLog.ToConsole($"Error - ReferenceSector has null value for {Player.PlayerId}.{GetType().Name}", MessageType.Error);
return;
}
transform.position = ReferenceSector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = ReferenceSector.Transform.InverseTransformRotation(SyncedTransform.rotation);
return;
}
2020-12-03 08:28:05 +00:00
// If this script is attached to any other body, eg the representations of other players
2020-12-02 21:29:53 +00:00
if (SyncedTransform.position == Vector3.zero)
{
Hide();
}
else
{
Show();
}
2021-02-19 13:23:14 +00:00
SyncedTransform.localPosition = SmartSmoothDamp(SyncedTransform.localPosition, transform.position);
2021-02-19 13:38:21 +00:00
SyncedTransform.localRotation = QuaternionHelper.SmoothDamp(SyncedTransform.localRotation, transform.rotation, ref _rotationSmoothVelocity, SmoothTime);
2020-12-02 21:29:53 +00:00
}
2021-02-19 13:23:14 +00:00
private Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
{
var distance = Vector3.Distance(currentPosition, targetPosition);
if (distance > _previousDistance + DistanceLeeway)
{
// moved too far! assume sector sync warp / actual warp
_previousDistance = distance;
return targetPosition;
}
_previousDistance = distance;
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
}
2020-12-02 21:29:53 +00:00
public void SetReferenceSector(QSBSector sector)
{
2021-02-28 15:35:01 +00:00
if (sector == ReferenceSector || sector == default(QSBSector))
2020-12-20 09:42:57 +00:00
{
return;
}
2020-12-02 21:29:53 +00:00
_positionSmoothVelocity = Vector3.zero;
ReferenceSector = sector;
if (!HasAuthority)
{
SyncedTransform.SetParent(sector.Transform, true);
transform.position = sector.Transform.InverseTransformPoint(SyncedTransform.position);
transform.rotation = sector.Transform.InverseTransformRotation(SyncedTransform.rotation);
}
}
private void Show()
{
if (!_isVisible)
{
SyncedTransform.gameObject.Show();
_isVisible = true;
}
}
private void Hide()
{
if (_isVisible)
{
SyncedTransform.gameObject.Hide();
_isVisible = false;
}
}
}
2020-08-31 09:36:29 +01:00
}