using System;
using FishNet.Utility.Extension;
using GameKit.Dependencies.Utilities;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace FishNet.Object.Prediction
{
[Obsolete("This class will be removed in version 5.")]
internal class LocalTransformTickSmoother : IResettable
{
#region Private.
///
/// Object to smooth.
///
private Transform _graphicalObject;
///
/// When not MoveRates.UNSET_VALUE the graphical object will teleport into it's next position if the move distance exceeds this value.
///
private float _teleportThreshold;
///
/// How quickly to move towards goal values.
///
private MoveRates _moveRates;
///
/// True if a pretick occurred since last postTick.
///
private bool _preTicked;
///
/// Local values of the graphical during pretick.
///
private TransformProperties _gfxInitializedLocalValues;
///
/// World values of the graphical after it's been aligned to initialized values in PreTick.
///
private TransformProperties _gfxPreSimulateWorldValues;
///
/// TickDelta on the TimeManager.
///
private float _tickDelta;
///
/// How many ticks to interpolate over.
///
private byte _interpolation;
#endregion
///
/// Initializes this smoother; should only be completed once.
///
internal void InitializeOnce(Transform graphicalObject, float teleportDistance, float tickDelta, byte interpolation)
{
_gfxInitializedLocalValues = graphicalObject.GetLocalProperties();
_tickDelta = tickDelta;
_graphicalObject = graphicalObject;
_teleportThreshold = (teleportDistance * (float)interpolation);
_interpolation = interpolation;
}
///
/// Called every frame.
///
internal void Update()
{
if (!CanSmooth())
return;
MoveToTarget();
}
///
/// Called when the TimeManager invokes OnPreTick.
///
internal void OnPreTick()
{
if (!CanSmooth())
return;
_preTicked = true;
_gfxPreSimulateWorldValues = _graphicalObject.GetWorldProperties();
}
///
/// Called when TimeManager invokes OnPostTick.
///
internal void OnPostTick()
{
if (!CanSmooth())
return;
//If preticked then previous transform values are known.
if (_preTicked)
{
_graphicalObject.SetWorldProperties(_gfxPreSimulateWorldValues);
SetMoveRates(_gfxInitializedLocalValues, _graphicalObject);
}
//If did not pretick then the only thing we can do is snap to instantiated values.
else
{
_graphicalObject.SetLocalProperties(_gfxInitializedLocalValues);
}
}
///
/// Returns if prediction can be used on this rigidbody.
///
///
private bool CanSmooth()
{
if (_graphicalObject == null)
return false;
return true;
}
///
/// Sets Position and Rotation move rates to reach Target datas.
///
private void SetMoveRates(TransformProperties prevValues, Transform t)
{
float duration = (_tickDelta * (float)_interpolation);
/* If interpolation is 1 then add on a tiny amount
* of more time to compensate for frame time, so that
* the smoothing does not complete before the next tick,
* as this would result in jitter. */
if (_interpolation == 1)
duration += Mathf.Max(Time.deltaTime, (1f / 50f));
float teleportT = _teleportThreshold;
_moveRates = MoveRates.GetLocalMoveRates(prevValues, t, duration, teleportT);
}
///
/// Moves transform to target values.
///
private void MoveToTarget()
{
_moveRates.Move(_graphicalObject, _gfxInitializedLocalValues, Time.deltaTime, useWorldSpace: false);
}
public void ResetState()
{
if (_graphicalObject != null)
{
_graphicalObject.SetLocalProperties(_gfxInitializedLocalValues);
_graphicalObject = null;
}
_teleportThreshold = default;
_moveRates = default;
_preTicked = default;
_gfxInitializedLocalValues = default;
_gfxPreSimulateWorldValues = default;
_tickDelta = default;
_interpolation = default;
}
public void InitializeState() { }
}
}