using FishNet.Managing.Timing; using FishNet.Object; using UnityEngine; namespace FishNet.Utility.Template { /// /// Subscribes to tick events making them available as virtual methods. /// public abstract class TickNetworkBehaviour : NetworkBehaviour { #region Types. [System.Flags] [System.Serializable] private enum TickCallback : int { None = 0, PreTick = 1, Tick = 2, PostTick = 4, All = ~0, } #endregion /// /// Tick callbacks to use. /// [Tooltip("Tick callbacks to use.")] [SerializeField] private TickCallback _tickCallbacks = (TickCallback.Tick | TickCallback.PostTick); /// /// Last subscription state. /// private bool _subscribed; internal override void OnStartNetwork_Internal() { base.OnStartNetwork_Internal(); ChangeSubscriptions(true); } internal override void OnStopNetwork_Internal() { base.OnStopNetwork_Internal(); ChangeSubscriptions(false); } private void ChangeSubscriptions(bool subscribe) { TimeManager tm = base.TimeManager; if (tm == null) return; if (subscribe == _subscribed) return; _subscribed = subscribe; if (subscribe) { if (TickCallbackContains(_tickCallbacks, TickCallback.PreTick)) tm.OnPreTick += TimeManager_OnPreTick; if (TickCallbackContains(_tickCallbacks, TickCallback.Tick)) tm.OnTick += TimeManager_OnTick; if (TickCallbackContains(_tickCallbacks, TickCallback.PostTick)) tm.OnPostTick += TimeManager_OnPostTick; } else { if (TickCallbackContains(_tickCallbacks, TickCallback.PreTick)) tm.OnPreTick -= TimeManager_OnPreTick; if (TickCallbackContains(_tickCallbacks, TickCallback.Tick)) tm.OnTick -= TimeManager_OnTick; if (TickCallbackContains(_tickCallbacks, TickCallback.PostTick)) tm.OnPostTick -= TimeManager_OnPostTick; } } protected virtual void TimeManager_OnPreTick() { } protected virtual void TimeManager_OnTick() { } protected virtual void TimeManager_OnPostTick() { } private bool TickCallbackContains(TickCallback whole, TickCallback part) => ((whole & part) == part); } }