using FishNet.Managing.Predicting; using FishNet.Managing.Timing; using FishNet.Object; using UnityEngine; namespace FishNet.Component.Prediction { public partial class OfflineRigidbody : MonoBehaviour { #region Serialized. /// <summary> /// Type of prediction movement which is being used. /// </summary> [Tooltip("Type of prediction movement which is being used.")] [SerializeField] private RigidbodyType _rigidbodyType; /// <summary> /// GraphicalObject to unparent when pausing. /// </summary> private Transform _graphicalObject; /// <summary> /// Sets GraphicalObject. /// </summary> /// <param name="value"></param> public void SetGraphicalObject(Transform value) { _graphicalObject = value; UpdateRigidbodies(); } /// <summary> /// True to also get rigidbody components within children. /// </summary> [Tooltip("True to also get rigidbody components within children.")] [SerializeField] private bool _getInChildren; #endregion #region Private. /// <summary> /// Pauser for rigidbodies. /// </summary> private RigidbodyPauser _rigidbodyPauser = new RigidbodyPauser(); /// <summary> /// TimeManager subscribed to. /// </summary> private PredictionManager _predictionManager; #endregion private void Awake() { InitializeOnce(); } private void OnDestroy() { ChangeSubscription(false); } /// <summary> /// Initializes this script for use. /// </summary> private void InitializeOnce() { _predictionManager = InstanceFinder.PredictionManager; UpdateRigidbodies(); ChangeSubscription(true); } /// <summary> /// Sets a new TimeManager to use. /// </summary> /// <param name="tm"></param> public void SetPredictionManager(PredictionManager pm) { if (pm == _predictionManager) return; //Unsub from current. ChangeSubscription(false); //Sub to newest. _predictionManager = pm; ChangeSubscription(true); } /// <summary> /// Finds and assigns rigidbodie using configured settings. /// </summary> public void UpdateRigidbodies() { _rigidbodyPauser.UpdateRigidbodies(transform, _rigidbodyType, _getInChildren, _graphicalObject); } /// <summary> /// Changes the subscription to the TimeManager. /// </summary> private void ChangeSubscription(bool subscribe) { if (_predictionManager == null) return; if (subscribe) { _predictionManager.OnPreReconcile += _predictionManager_OnPreReconcile; _predictionManager.OnPostReconcile += _predictionManager_OnPostReconcile; } else { _predictionManager.OnPreReconcile -= _predictionManager_OnPreReconcile; _predictionManager.OnPostReconcile -= _predictionManager_OnPostReconcile; } } private void _predictionManager_OnPreReconcile(NetworkBehaviour obj) { //Make rbs all kinematic/!simulated before reconciling, which would also result in replays. _rigidbodyPauser.Pause(); } private void _predictionManager_OnPostReconcile(NetworkBehaviour obj) { _rigidbodyPauser.Unpause(); } } }