Guest User

Untitled

a guest
Aug 28th, 2024
17
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.46 KB | None | 0 0
  1. п»їusing FishNet.Component.Observing;
  2. using FishNet.Connection;
  3. using FishNet.Managing;
  4. using FishNet.Observing;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Runtime.CompilerServices;
  8. using UnityEngine;
  9.  
  10. namespace FishNet.Object
  11. {
  12.     public partial class NetworkObject : MonoBehaviour
  13.     {
  14.         #region Public.
  15.         /// <summary>
  16.         /// Called when the clientHost gains or loses visibility of this object.
  17.         /// Boolean value will be true if clientHost has visibility.
  18.         /// </summary>        
  19.         public event HostVisibilityUpdatedDelegate OnHostVisibilityUpdated;
  20.         /// <summary>
  21.         ///
  22.         /// </summary>
  23.         /// <param name="prevVisible">True if clientHost was known to have visibility of the object prior to this invoking.</param>
  24.         /// <param name="nextVisible">True if the clientHost now has visibility of the object.</param>
  25.         public delegate void HostVisibilityUpdatedDelegate(bool prevVisible, bool nextVisible);
  26.         /// <summary>
  27.         /// Called when this NetworkObject losses all observers or gains observers while previously having none.
  28.         /// </summary>
  29.         public event Action<NetworkObject> OnObserversActive;
  30.         /// <summary>
  31.         /// NetworkObserver on this object.
  32.         /// </summary>
  33.         [HideInInspector]
  34.         public NetworkObserver NetworkObserver = null;
  35.         /// <summary>
  36.         /// Clients which can see and get messages from this NetworkObject.
  37.         /// </summary>
  38.         [HideInInspector]
  39.         public HashSet<NetworkConnection> Observers = new HashSet<NetworkConnection>();
  40.         #endregion
  41.  
  42.         #region Internal.
  43.         /// <summary>
  44.         /// Current HashGrid entry this belongs to.
  45.         /// </summary>
  46.         internal GridEntry HashGridEntry;
  47.         #endregion
  48.  
  49.         #region Private.
  50.         /// <summary>
  51.         /// True if NetworkObserver has been initialized.
  52.         /// </summary>
  53.         private bool _networkObserverInitiliazed = false;
  54.         /// <summary>
  55.         /// Found renderers on the NetworkObject and it's children. This is only used as clientHost to hide non-observers objects.
  56.         /// </summary>
  57.         [System.NonSerialized]
  58.         private Renderer[] _renderers;
  59.         /// <summary>
  60.         /// True if renderers have been looked up.
  61.         /// </summary>
  62.         private bool _renderersPopulated;
  63.         /// <summary>
  64.         /// Last visibility value for clientHost on this object.
  65.         /// </summary>
  66.         private bool _lastClientHostVisibility;
  67.         /// <summary>
  68.         /// HashGrid for this object.
  69.         /// </summary>
  70.         private HashGrid _hashGrid;
  71.         /// <summary>
  72.         /// Next time this object may update it's position for HashGrid.
  73.         /// </summary>
  74.         private float _nextHashGridUpdateTime;
  75.         /// <summary>
  76.         /// True if this gameObject is static.
  77.         /// </summary>
  78.         private bool _isStatic;
  79.         /// <summary>
  80.         /// Current grid position.
  81.         /// </summary>
  82.         private Vector2Int _hashGridPosition = HashGrid.UnsetGridPosition;
  83.         #endregion
  84.  
  85.         private bool disableSets = true;
  86.  
  87.         /// <summary>
  88.         /// Updates Objects positions in the HashGrid for this Networkmanager.
  89.         /// </summary>
  90.         internal void UpdateForNetworkObject(bool force)
  91.         {
  92.             if (_hashGrid == null)
  93.                 return;
  94.             if (_isStatic)
  95.                 return;
  96.  
  97.             float unscaledTime = Time.unscaledTime;
  98.             //Not enough time has passed to update.
  99.             if (!force && unscaledTime < _nextHashGridUpdateTime)
  100.                 return;
  101.  
  102.             const float updateInterval = 1f;
  103.             _nextHashGridUpdateTime = unscaledTime + updateInterval;
  104.             Vector2Int newPosition = _hashGrid.GetHashGridPosition(this);
  105.             if (newPosition != _hashGridPosition)
  106.             {
  107.                 _hashGridPosition = newPosition;
  108.                 HashGridEntry = _hashGrid.GetGridEntry(newPosition);
  109.             }            
  110.         }
  111.  
  112.         /// <summary>
  113.         /// Updates cached renderers used to managing clientHost visibility.
  114.         /// </summary>
  115.         /// <param name="updateVisibility">True to also update visibility if clientHost.</param>
  116.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
  117.         public void UpdateRenderers(bool updateVisibility = true)
  118.         {
  119.             if (disableSets)
  120.                 return;
  121.  
  122.             UpdateRenderers_Internal(updateVisibility);
  123.         }
  124.  
  125.         /// <summary>
  126.         /// Sets the renderer visibility for clientHost.
  127.         /// </summary>
  128.         /// <param name="visible">True if renderers are to be visibile.</param>
  129.         /// <param name="force">True to skip blocking checks.</param>
  130.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
  131.         public void SetRenderersVisible(bool visible, bool force = false)
  132.         {
  133.             if (disableSets)
  134.                 return;
  135.  
  136.             if (!force)
  137.             {
  138.                 if (!NetworkObserver.UpdateHostVisibility)
  139.                     return;
  140.             }
  141.  
  142.             if (!_renderersPopulated)
  143.             {
  144.                 UpdateRenderers_Internal(false);
  145.                 _renderersPopulated = true;
  146.             }
  147.  
  148.             UpdateRenderVisibility(visible);
  149.         }
  150.  
  151.         /// <summary>
  152.         /// Clears and updates renderers.
  153.         /// </summary>
  154.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
  155.         private void UpdateRenderers_Internal(bool updateVisibility)
  156.         {
  157.             if (disableSets)
  158.                 return;
  159.  
  160.             _renderers = GetComponentsInChildren<Renderer>(true);
  161.             List<Renderer> enabledRenderers = new List<Renderer>();
  162.             foreach (Renderer r in _renderers)
  163.             {
  164.                 if (r.enabled)
  165.                     enabledRenderers.Add(r);
  166.             }
  167.             //If there are any disabled renderers then change _renderers to cached values.
  168.             if (enabledRenderers.Count != _renderers.Length)
  169.                 _renderers = enabledRenderers.ToArray();
  170.  
  171.             if (updateVisibility)
  172.                 UpdateRenderVisibility(_lastClientHostVisibility);
  173.         }
  174.  
  175.         /// <summary>
  176.         /// Updates visibilites on renders without checks.
  177.         /// </summary>
  178.         /// <param name="visible"></param>
  179.         private void UpdateRenderVisibility(bool visible)
  180.         {
  181.             bool rebuildRenderers = false;
  182.  
  183.             Renderer[] rs = _renderers;
  184.             int count = rs.Length;
  185.             for (int i = 0; i < count; i++)
  186.             {
  187.                 Renderer r = rs[i];
  188.                 if (r == null)
  189.                 {
  190.                     rebuildRenderers = true;
  191.                     break;
  192.                 }
  193.  
  194.                 r.enabled = visible;
  195.             }
  196.  
  197.             OnHostVisibilityUpdated?.Invoke(_lastClientHostVisibility, visible);
  198.             _lastClientHostVisibility = visible;
  199.  
  200.             //If to rebuild then do so, while updating visibility.
  201.             if (rebuildRenderers)
  202.                 UpdateRenderers(true);
  203.         }
  204.  
  205.         /// <summary>
  206.         /// Adds the default NetworkObserver conditions using the ObserverManager.
  207.         /// </summary>
  208.         private void AddDefaultNetworkObserverConditions()
  209.         {
  210.             if (_networkObserverInitiliazed)
  211.                 return;
  212.  
  213.             NetworkObserver = NetworkManager.ObserverManager.AddDefaultConditions(this);
  214.         }
  215.  
  216.  
  217.         /// <summary>
  218.         /// Removes a connection from observers for this object returning if the connection was removed.
  219.         /// </summary>
  220.         /// <param name="connection"></param>
  221.         internal bool RemoveObserver(NetworkConnection connection)
  222.         {
  223.             int startCount = Observers.Count;
  224.             bool removed = Observers.Remove(connection);
  225.             if (removed)
  226.                 TryInvokeOnObserversActive(startCount);
  227.  
  228.             return removed;
  229.         }
  230.  
  231.         /// <summary>
  232.         /// Adds the connection to observers if conditions are met.
  233.         /// </summary>
  234.         /// <param name="connection"></param>
  235.         /// <returns>True if added to Observers.</returns>
  236.         internal ObserverStateChange RebuildObservers(NetworkConnection connection, bool timedOnly)
  237.         {
  238.             //If not a valid connection.
  239.             if (!connection.IsValid)
  240.             {
  241.                 NetworkManager.LogWarning($"An invalid connection was used when rebuilding observers.");
  242.                 return ObserverStateChange.Unchanged;
  243.             }
  244.             //Valid not not active.
  245.             else if (!connection.IsActive)
  246.             {
  247.                 /* Just remove from observers since connection isn't active
  248.                  * and return unchanged because nothing should process
  249.                  * given the connection isnt active. */
  250.                 Observers.Remove(connection);
  251.                 return ObserverStateChange.Unchanged;
  252.             }
  253.             else if (IsDeinitializing)
  254.             {
  255.                 /* If object is deinitializing it's either being despawned
  256.                  * this frame or it's not spawned. If we've made it this far,
  257.                  * it's most likely being despawned. */
  258.                 return ObserverStateChange.Unchanged;
  259.             }
  260.  
  261.             //Update hashgrid if needed.
  262.             UpdateForNetworkObject(!timedOnly);
  263.  
  264.             int startCount = Observers.Count;
  265.             ObserverStateChange osc = NetworkObserver.RebuildObservers(connection, timedOnly);
  266.  
  267.             if (osc == ObserverStateChange.Added)
  268.                 Observers.Add(connection);
  269.             else if (osc == ObserverStateChange.Removed)
  270.                 Observers.Remove(connection);
  271.  
  272.             if (osc != ObserverStateChange.Unchanged)
  273.                 TryInvokeOnObserversActive(startCount);
  274.  
  275.             return osc;
  276.         }
  277.  
  278.         /// <summary>
  279.         /// Invokes OnObserversActive if observers are now 0 but previously were not, or if was previously 0 but now has observers.
  280.         /// </summary>
  281.         /// <param name="startCount"></param>
  282.         private void TryInvokeOnObserversActive(int startCount)
  283.         {
  284.             if ((Observers.Count > 0 && startCount == 0) ||
  285.                 Observers.Count == 0 && startCount > 0)
  286.                 OnObserversActive?.Invoke(this);
  287.         }
  288.  
  289.     }
  290.  
  291. }
  292.  
  293.  
Advertisement
Add Comment
Please, Sign In to add comment