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() { } } }