using FishNet.Managing;
using FishNet.Managing.Timing;
using GameKit.Dependencies.Utilities;
using UnityEngine;
using UnityEngine.Serialization;
namespace FishNet.Component.Transforming.Beta
{
///
/// Smoothes this object between ticks.
///
/// This can be configured to smooth over a set interval of time, or to smooth adaptively and make path corrections for prediction.
public class OfflineTickSmoother : MonoBehaviour
{
#region Public.
///
/// Logic for owner smoothing.
///
public TickSmootherController SmootherController { get; private set; }
///
/// True if this component is initialized.
///
/// This API is for internal use and may change at any time.
public bool IsInitialized { get; private set; }
#endregion
#region Serialized.
///
/// True to automatically initialize in Awake using InstanceFinder. When false you will need to manually call Initialize.
///
[Tooltip("True to automatically initialize in Awake using InstanceFinder. When false you will need to manually call Initialize.")]
[SerializeField]
private bool _automaticallyInitialize = true;
///
/// Settings required to initialize the smoother.
///
[Tooltip("Settings required to initialize the smoother.")]
[SerializeField]
private InitializationSettings _initializationSettings = new();
///
/// How smoothing occurs when the controller of the object.
///
[FormerlySerializedAs("_controllerMovementSettings")]
[Tooltip("How smoothing occurs when the controller of the object.")]
[SerializeField]
private MovementSettings _movementSettings = new(true);
#endregion
private void Awake()
{
RetrieveControllers();
AutomaticallyInitialize();
}
private void OnDestroy()
{
if (SmootherController != null)
{
SmootherController.StopSmoother();
SmootherController.OnDestroy();
}
StoreControllers();
IsInitialized = false;
}
///
/// Automatically initializes if feature is enabled.
///
private void AutomaticallyInitialize()
{
if (!_automaticallyInitialize)
return;
TimeManager tm = InstanceFinder.TimeManager;
if (tm == null)
{
NetworkManagerExtensions.LogWarning($"Automatic initialization failed on {gameObject.name}. You must manually call Initialize.");
return;
}
Initialize(tm);
}
///
/// Initializes using a specified TimeManager.
///
///
public void Initialize(TimeManager timeManager)
{
if (timeManager == null)
{
NetworkManagerExtensions.LogError($"TimeManager cannot be null when initializing.");
return;
}
SmootherController.SetTimeManager(timeManager);
_initializationSettings.SetOfflineRuntimeValues(timeManager, graphicalTransform: transform);
SmootherController.Initialize(_initializationSettings, _movementSettings, default);
SmootherController.StartSmoother();
IsInitialized = true;
}
///
/// Sets a transform as the target to follow.
///
/// New value.
public void SetTargetTransform(Transform value)
{
if (IsInitialized)
{
NetworkManagerExtensions.LogError($"Target can only be set before Initialize is called.");
return;
}
_initializationSettings.TargetTransform = value;
}
///
/// Stores smoothers if they have value.
///
private void StoreControllers()
{
if (SmootherController == null)
return;
ResettableObjectCaches.Store(SmootherController);
SmootherController = null;
}
///
/// Stores current smoothers and retrieves new ones.
///
private void RetrieveControllers()
{
StoreControllers();
SmootherController = ResettableObjectCaches.Retrieve();
}
}
}