Add StickGame Assets
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
using FishNet.Component.Observing;
|
||||
using FishNet.Connection;
|
||||
using FishNet.Observing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Object
|
||||
{
|
||||
public partial class NetworkObject : MonoBehaviour
|
||||
{
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Called when the clientHost gains or loses visibility of this object.
|
||||
/// Boolean value will be true if clientHost has visibility.
|
||||
/// </summary>
|
||||
public event HostVisibilityUpdatedDelegate OnHostVisibilityUpdated;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="prevVisible">True if clientHost was known to have visibility of the object prior to this invoking.</param>
|
||||
/// <param name="nextVisible">True if the clientHost now has visibility of the object.</param>
|
||||
public delegate void HostVisibilityUpdatedDelegate(bool prevVisible, bool nextVisible);
|
||||
/// <summary>
|
||||
/// Called when this NetworkObject losses all observers or gains observers while previously having none.
|
||||
/// </summary>
|
||||
public event Action<NetworkObject> OnObserversActive;
|
||||
/// <summary>
|
||||
/// NetworkObserver on this object.
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
public NetworkObserver NetworkObserver = null;
|
||||
/// <summary>
|
||||
/// Clients which can see and get messages from this NetworkObject.
|
||||
/// </summary>
|
||||
[HideInInspector]
|
||||
public HashSet<NetworkConnection> Observers = new HashSet<NetworkConnection>();
|
||||
#endregion
|
||||
|
||||
#region Internal.
|
||||
/// <summary>
|
||||
/// Current HashGrid entry this belongs to.
|
||||
/// </summary>
|
||||
internal GridEntry HashGridEntry;
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// True if NetworkObserver has been initialized.
|
||||
/// </summary>
|
||||
private bool _networkObserverInitiliazed = false;
|
||||
/// <summary>
|
||||
/// Found renderers on the NetworkObject and it's children. This is only used as clientHost to hide non-observers objects.
|
||||
/// </summary>
|
||||
[System.NonSerialized]
|
||||
private Renderer[] _renderers;
|
||||
/// <summary>
|
||||
/// True if renderers have been looked up.
|
||||
/// </summary>
|
||||
private bool _renderersPopulated;
|
||||
/// <summary>
|
||||
/// Last visibility value for clientHost on this object.
|
||||
/// </summary>
|
||||
private bool _lastClientHostVisibility;
|
||||
/// <summary>
|
||||
/// HashGrid for this object.
|
||||
/// </summary>
|
||||
private HashGrid _hashGrid;
|
||||
/// <summary>
|
||||
/// Next time this object may update it's position for HashGrid.
|
||||
/// </summary>
|
||||
private float _nextHashGridUpdateTime;
|
||||
/// <summary>
|
||||
/// True if this gameObject is static.
|
||||
/// </summary>
|
||||
private bool _isStatic;
|
||||
/// <summary>
|
||||
/// Current grid position.
|
||||
/// </summary>
|
||||
private Vector2Int _hashGridPosition = HashGrid.UnsetGridPosition;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Updates Objects positions in the HashGrid for this Networkmanager.
|
||||
/// </summary>
|
||||
internal void UpdateForNetworkObject(bool force)
|
||||
{
|
||||
if (_hashGrid == null)
|
||||
return;
|
||||
if (_isStatic)
|
||||
return;
|
||||
|
||||
float unscaledTime = Time.unscaledTime;
|
||||
//Not enough time has passed to update.
|
||||
if (!force && unscaledTime < _nextHashGridUpdateTime)
|
||||
return;
|
||||
|
||||
const float updateInterval = 1f;
|
||||
_nextHashGridUpdateTime = unscaledTime + updateInterval;
|
||||
Vector2Int newPosition = _hashGrid.GetHashGridPosition(this);
|
||||
if (newPosition != _hashGridPosition)
|
||||
{
|
||||
_hashGridPosition = newPosition;
|
||||
HashGridEntry = _hashGrid.GetGridEntry(newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates cached renderers used to managing clientHost visibility.
|
||||
/// </summary>
|
||||
/// <param name="updateVisibility">True to also update visibility if clientHost.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void UpdateRenderers(bool updateVisibility = true)
|
||||
{
|
||||
UpdateRenderers_Internal(updateVisibility);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the renderer visibility for clientHost.
|
||||
/// </summary>
|
||||
/// <param name="visible">True if renderers are to be visibile.</param>
|
||||
/// <param name="force">True to skip blocking checks.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetRenderersVisible(bool visible, bool force = false)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
if (!NetworkObserver.UpdateHostVisibility)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_renderersPopulated)
|
||||
{
|
||||
UpdateRenderers_Internal(false);
|
||||
_renderersPopulated = true;
|
||||
}
|
||||
|
||||
UpdateRenderVisibility(visible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears and updates renderers.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void UpdateRenderers_Internal(bool updateVisibility)
|
||||
{
|
||||
_renderers = GetComponentsInChildren<Renderer>(true);
|
||||
List<Renderer> enabledRenderers = new List<Renderer>();
|
||||
foreach (Renderer r in _renderers)
|
||||
{
|
||||
if (r.enabled)
|
||||
enabledRenderers.Add(r);
|
||||
}
|
||||
//If there are any disabled renderers then change _renderers to cached values.
|
||||
if (enabledRenderers.Count != _renderers.Length)
|
||||
_renderers = enabledRenderers.ToArray();
|
||||
|
||||
if (updateVisibility)
|
||||
UpdateRenderVisibility(_lastClientHostVisibility);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates visibilites on renders without checks.
|
||||
/// </summary>
|
||||
/// <param name="visible"></param>
|
||||
private void UpdateRenderVisibility(bool visible)
|
||||
{
|
||||
bool rebuildRenderers = false;
|
||||
|
||||
Renderer[] rs = _renderers;
|
||||
int count = rs.Length;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Renderer r = rs[i];
|
||||
if (r == null)
|
||||
{
|
||||
rebuildRenderers = true;
|
||||
break;
|
||||
}
|
||||
|
||||
r.enabled = visible;
|
||||
}
|
||||
|
||||
OnHostVisibilityUpdated?.Invoke(_lastClientHostVisibility, visible);
|
||||
_lastClientHostVisibility = visible;
|
||||
|
||||
//If to rebuild then do so, while updating visibility.
|
||||
if (rebuildRenderers)
|
||||
UpdateRenderers(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the default NetworkObserver conditions using the ObserverManager.
|
||||
/// </summary>
|
||||
private void AddDefaultNetworkObserverConditions()
|
||||
{
|
||||
if (_networkObserverInitiliazed)
|
||||
return;
|
||||
|
||||
NetworkObserver = NetworkManager.ObserverManager.AddDefaultConditions(this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Removes a connection from observers for this object returning if the connection was removed.
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
internal bool RemoveObserver(NetworkConnection connection)
|
||||
{
|
||||
int startCount = Observers.Count;
|
||||
bool removed = Observers.Remove(connection);
|
||||
if (removed)
|
||||
TryInvokeOnObserversActive(startCount);
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the connection to observers if conditions are met.
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
/// <returns>True if added to Observers.</returns>
|
||||
internal ObserverStateChange RebuildObservers(NetworkConnection connection, bool timedOnly)
|
||||
{
|
||||
//If not a valid connection.
|
||||
if (!connection.IsValid)
|
||||
{
|
||||
NetworkManager.LogWarning($"An invalid connection was used when rebuilding observers.");
|
||||
return ObserverStateChange.Unchanged;
|
||||
}
|
||||
//Valid not not active.
|
||||
else if (!connection.IsActive)
|
||||
{
|
||||
/* Just remove from observers since connection isn't active
|
||||
* and return unchanged because nothing should process
|
||||
* given the connection isnt active. */
|
||||
Observers.Remove(connection);
|
||||
return ObserverStateChange.Unchanged;
|
||||
}
|
||||
else if (IsDeinitializing)
|
||||
{
|
||||
/* If object is deinitializing it's either being despawned
|
||||
* this frame or it's not spawned. If we've made it this far,
|
||||
* it's most likely being despawned. */
|
||||
return ObserverStateChange.Unchanged;
|
||||
}
|
||||
|
||||
//Update hashgrid if needed.
|
||||
UpdateForNetworkObject(!timedOnly);
|
||||
|
||||
int startCount = Observers.Count;
|
||||
ObserverStateChange osc = NetworkObserver.RebuildObservers(connection, timedOnly);
|
||||
|
||||
if (osc == ObserverStateChange.Added)
|
||||
Observers.Add(connection);
|
||||
else if (osc == ObserverStateChange.Removed)
|
||||
Observers.Remove(connection);
|
||||
|
||||
if (osc != ObserverStateChange.Unchanged)
|
||||
TryInvokeOnObserversActive(startCount);
|
||||
|
||||
return osc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes OnObserversActive if observers are now 0 but previously were not, or if was previously 0 but now has observers.
|
||||
/// </summary>
|
||||
/// <param name="startCount"></param>
|
||||
private void TryInvokeOnObserversActive(int startCount)
|
||||
{
|
||||
if ((Observers.Count > 0 && startCount == 0) ||
|
||||
Observers.Count == 0 && startCount > 0)
|
||||
OnObserversActive?.Invoke(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user