Add FishNet network library
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3549ac1479ae014986f98b9f63e3011
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Managing.Observing.Editing
|
||||
{
|
||||
[CustomEditor(typeof(ObserverManager), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class ObserverManagerEditor : Editor
|
||||
{
|
||||
private SerializedProperty _updateHostVisibility;
|
||||
private SerializedProperty _maximumTimedObserversDuration;
|
||||
private SerializedProperty _defaultConditions
|
||||
;
|
||||
private SerializedProperty _useLevelOfDetail;
|
||||
private SerializedProperty _maximumLevelOfDetailInterval;
|
||||
private SerializedProperty _levelOfDetailUpdateDuration;
|
||||
|
||||
private SerializedProperty _levelOfDetailDistances;
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
_updateHostVisibility = serializedObject.FindProperty(nameof(_updateHostVisibility));
|
||||
_maximumTimedObserversDuration = serializedObject.FindProperty(nameof(_maximumTimedObserversDuration));
|
||||
_defaultConditions = serializedObject.FindProperty(nameof(_defaultConditions));
|
||||
|
||||
_useLevelOfDetail = serializedObject.FindProperty(nameof(_useLevelOfDetail));
|
||||
_maximumLevelOfDetailInterval = serializedObject.FindProperty(nameof(_maximumLevelOfDetailInterval));
|
||||
_levelOfDetailUpdateDuration = serializedObject.FindProperty(nameof(_levelOfDetailUpdateDuration));
|
||||
_levelOfDetailDistances = serializedObject.FindProperty(nameof(_levelOfDetailDistances));
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.ObjectField("Script:", MonoScript.FromMonoBehaviour((ObserverManager)target), typeof(ObserverManager), false);
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUILayout.LabelField("Observers", EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUILayout.PropertyField(_updateHostVisibility);
|
||||
if (_maximumTimedObserversDuration.floatValue < 1d)
|
||||
EditorGUILayout.HelpBox("Using low values may reduce server performance while under load.", MessageType.Warning);
|
||||
EditorGUILayout.PropertyField(_maximumTimedObserversDuration);
|
||||
EditorGUILayout.PropertyField(_defaultConditions);
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.LabelField("Level of Detail *", EditorStyles.boldLabel);
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
if (Application.isPlaying)
|
||||
GUI.enabled = false;
|
||||
|
||||
EditorGUILayout.PropertyField(_useLevelOfDetail);
|
||||
if (_useLevelOfDetail.boolValue)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(_maximumLevelOfDetailInterval, new GUIContent("Maximum Send Interval"));
|
||||
EditorGUILayout.PropertyField(_levelOfDetailUpdateDuration, new GUIContent("Recalculation Duration"));
|
||||
|
||||
EditorGUILayout.PropertyField(_levelOfDetailDistances);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86e21ffc228c07d4891b6e74080b8c90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.7.3R
|
||||
assetPath: Assets/FishNet/Runtime/Managing/Observing/Editor/ObserverManagerEditor.cs
|
||||
uploadId: 987062
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace FishNet.Managing.Observing
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A configuration which affects the level of detail for a connection.
|
||||
/// </summary>
|
||||
public struct LevelOfDetail
|
||||
{
|
||||
/// <summary>
|
||||
/// How often data will send when on this level of detail.
|
||||
/// </summary>
|
||||
public ushort SendInterval;
|
||||
|
||||
/// <summary>
|
||||
/// Distance a connection's objects must be within to use this LevelOfDetail.
|
||||
/// </summary>
|
||||
public ushort Distance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 573375ac2883b974c9201b040a432f76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.7.3R
|
||||
assetPath: Assets/FishNet/Runtime/Managing/Observing/LevelOfDetail.cs
|
||||
uploadId: 987062
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FishNet.Connection;
|
||||
using FishNet.Managing.Timing;
|
||||
using FishNet.Object;
|
||||
using FishNet.Utility;
|
||||
using GameKit.Dependencies.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace FishNet.Managing.Observing
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles level of detail actions.
|
||||
/// </summary>
|
||||
public sealed partial class ObserverManager : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Most recent LocalTick value on the TimeManager.
|
||||
/// </summary>
|
||||
internal uint LocalTick;
|
||||
[Tooltip("True to enable level of detail.")]
|
||||
[SerializeField]
|
||||
private bool _useLevelOfDetail;
|
||||
/// <summary>
|
||||
/// The maximum delay between updates when an object is using the highest level of detail.
|
||||
/// </summary>
|
||||
[Tooltip("The maximum delay between updates when an object is using the highest level of detail.")]
|
||||
[Range(MINIMUM_LEVEL_OF_DETAIL_SEND_INTERVAL, MAXIMUM_LEVEL_OF_DETAIL_SEND_INTERVAL)]
|
||||
[SerializeField]
|
||||
private float _maximumLevelOfDetailInterval = 2f;
|
||||
/// <summary>
|
||||
/// The time it will take to calculate new level of detail values.
|
||||
/// </summary>
|
||||
[Tooltip("The time it will take to calculate new level of detail values.")]
|
||||
[Range(MINIMUM_LEVEL_OF_DETAIL_UPDATE_DURATION, MAXIMUM_LEVEL_OF_DETAIL_UPDATE_DURATION)]
|
||||
[SerializeField]
|
||||
private float _levelOfDetailUpdateDuration = 1f;
|
||||
/// <summary>
|
||||
/// Distances for each level of detail change. Each distance is an exponential increase. When the largest distance is surpassed the maximum delay is used; while within the first distance standard delays are used.
|
||||
/// </summary>
|
||||
[Tooltip("Distances for each level of detail change. Each distance is an exponential increase. When the largest distance is surpassed the maximum delay is used; while within the first distance standard delays are used.")]
|
||||
[SerializeField]
|
||||
private List<float> _levelOfDetailDistances = new();
|
||||
#region Consts.
|
||||
/// <summary>
|
||||
/// Minimum time allowed for the maximum level of detail send interval.
|
||||
/// </summary>
|
||||
private const float MINIMUM_LEVEL_OF_DETAIL_SEND_INTERVAL = 0.1f;
|
||||
/// <summary>
|
||||
/// Maximum time allowed for the maximum level of detail send interval.
|
||||
/// </summary>
|
||||
private const float MAXIMUM_LEVEL_OF_DETAIL_SEND_INTERVAL = 15f;
|
||||
/// <summary>
|
||||
/// Minimum time which can be used for the level of detail update duration.
|
||||
/// </summary>
|
||||
private const float MINIMUM_LEVEL_OF_DETAIL_UPDATE_DURATION = 0.5f;
|
||||
/// <summary>
|
||||
/// Maximum time which can be used for the level of detail update duration.
|
||||
/// </summary>
|
||||
private const float MAXIMUM_LEVEL_OF_DETAIL_UPDATE_DURATION = 10f;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes for level of detail use.
|
||||
/// </summary>
|
||||
/// <returns>New UseLevelOfDetail value.</returns>
|
||||
private bool InitializeLevelOfDetailValues()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the duration of how long level of update values should be recalculated.
|
||||
/// </summary>
|
||||
public void SetLevelOfDetailRecalculationDuration(float duration) => _levelOfDetailUpdateDuration = Mathf.Clamp(duration, MINIMUM_LEVEL_OF_DETAIL_UPDATE_DURATION, MAXIMUM_LEVEL_OF_DETAIL_UPDATE_DURATION);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72fa5d7278196bd4f82ad85cd7d20038
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bf9191e2e07d29749bca3a1ae44e4bc8, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.7.3R
|
||||
assetPath: Assets/FishNet/Runtime/Managing/Observing/ObserverManager.LevelOfDetail.cs
|
||||
uploadId: 987062
|
||||
@@ -0,0 +1,219 @@
|
||||
using FishNet.Connection;
|
||||
using FishNet.Object;
|
||||
using FishNet.Observing;
|
||||
using FishNet.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FishNet.Managing.Timing;
|
||||
using UnityEngine;
|
||||
|
||||
[assembly: InternalsVisibleTo(UtilityConstants.DEMOS_ASSEMBLY_NAME)]
|
||||
[assembly: InternalsVisibleTo(UtilityConstants.TEST_ASSEMBLY_NAME)]
|
||||
|
||||
namespace FishNet.Managing.Observing
|
||||
{
|
||||
/// <summary>
|
||||
/// Additional options for managing the observer system.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("FishNet/Manager/ObserverManager")]
|
||||
public sealed partial class ObserverManager : MonoBehaviour
|
||||
{
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// True to update visibility for clientHost based on if they are an observer or not.
|
||||
/// </summary>
|
||||
public bool UpdateHostVisibility
|
||||
{
|
||||
get => _updateHostVisibility;
|
||||
private set => _updateHostVisibility = value;
|
||||
}
|
||||
[Tooltip("True to update visibility for clientHost based on if they are an observer or not.")]
|
||||
[SerializeField]
|
||||
private bool _updateHostVisibility = true;
|
||||
/// <summary>
|
||||
/// Maximum duration the server will take to update timed observer conditions as server load increases. Lower values will result in timed conditions being checked quicker at the cost of performance..
|
||||
/// </summary>
|
||||
public float MaximumTimedObserversDuration
|
||||
{
|
||||
get => _maximumTimedObserversDuration;
|
||||
private set => _maximumTimedObserversDuration = value;
|
||||
}
|
||||
[Tooltip("Maximum duration the server will take to update timed observer conditions as server load increases. Lower values will result in timed conditions being checked quicker at the cost of performance.")]
|
||||
[SerializeField]
|
||||
[Range(MINIMUM_TIMED_OBSERVERS_DURATION, MAXIMUM_TIMED_OBSERVERS_DURATION)]
|
||||
private float _maximumTimedObserversDuration = 10f;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the MaximumTimedObserversDuration value.
|
||||
/// </summary>
|
||||
/// <param name = "value">New maximum duration to update timed observers over.</param>
|
||||
public void SetMaximumTimedObserversDuration(float value) => MaximumTimedObserversDuration = System.Math.Clamp(value, MINIMUM_TIMED_OBSERVERS_DURATION, MAXIMUM_TIMED_OBSERVERS_DURATION);
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Tooltip("Default observer conditions for networked objects.")]
|
||||
[SerializeField]
|
||||
private List<ObserverCondition> _defaultConditions = new();
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// NetworkManager on object.
|
||||
/// </summary>
|
||||
private NetworkManager _networkManager;
|
||||
#endregion
|
||||
|
||||
#region Consts.
|
||||
/// <summary>
|
||||
/// Minimum time allowed for timed observers to rebuild.
|
||||
/// </summary>
|
||||
private const float MINIMUM_TIMED_OBSERVERS_DURATION = 0.1f;
|
||||
/// <summary>
|
||||
/// Maximum time allowed for timed observers to rebuild.
|
||||
/// </summary>
|
||||
private const float MAXIMUM_TIMED_OBSERVERS_DURATION = 20f;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use.
|
||||
/// </summary>
|
||||
/// <param name = "manager"></param>
|
||||
internal void InitializeOnce_Internal(NetworkManager manager)
|
||||
{
|
||||
_networkManager = manager;
|
||||
// Update the current value to itself so it becomes clamped. This is just to protect against the user manually setting it outside clamp somehow.
|
||||
SetMaximumTimedObserversDuration(MaximumTimedObserversDuration);
|
||||
|
||||
_useLevelOfDetail = InitializeLevelOfDetailValues();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a new value for UpdateHostVisibility.
|
||||
/// </summary>
|
||||
/// <param name = "value">New value.</param>
|
||||
/// <param name = "updateType">Which objects to update.</param>
|
||||
public void SetUpdateHostVisibility(bool value, HostVisibilityUpdateTypes updateType)
|
||||
{
|
||||
// Unchanged.
|
||||
if (value == UpdateHostVisibility)
|
||||
return;
|
||||
|
||||
/* Update even if server state is not known.
|
||||
* The setting should be updated so when the server
|
||||
* does start spawned objects have latest setting. */
|
||||
if (HostVisibilityUpdateContains(updateType, HostVisibilityUpdateTypes.Manager))
|
||||
UpdateHostVisibility = value;
|
||||
|
||||
/* If to update spawned as well then update all networkobservers
|
||||
* with the setting and also update renderers. */
|
||||
if (_networkManager.IsServerStarted && HostVisibilityUpdateContains(updateType, HostVisibilityUpdateTypes.Spawned))
|
||||
{
|
||||
NetworkConnection clientConn = _networkManager.ClientManager.Connection;
|
||||
foreach (NetworkObject n in _networkManager.ServerManager.Objects.Spawned.Values)
|
||||
{
|
||||
n.NetworkObserver.SetUpdateHostVisibility(value);
|
||||
|
||||
// Only check to update renderers if clientHost. If not client then clientConn won't be active.
|
||||
if (clientConn.IsActive)
|
||||
n.SetRenderersVisible(n.Observers.Contains(clientConn), true);
|
||||
}
|
||||
}
|
||||
|
||||
bool HostVisibilityUpdateContains(HostVisibilityUpdateTypes whole, HostVisibilityUpdateTypes part)
|
||||
{
|
||||
return (whole & part) == part;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds default observer conditions to nob and returns the NetworkObserver used.
|
||||
/// </summary>
|
||||
internal NetworkObserver AddDefaultConditions(NetworkObject nob)
|
||||
{
|
||||
bool isGlobal = nob.IsGlobal && !nob.IsSceneObject;
|
||||
bool obsAdded;
|
||||
|
||||
NetworkObserver result;
|
||||
if (!nob.TryGetComponent(out result))
|
||||
{
|
||||
obsAdded = true;
|
||||
result = nob.gameObject.AddComponent<NetworkObserver>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If already setup by this manager then return.
|
||||
if (result.ConditionsSetByObserverManager)
|
||||
return result;
|
||||
|
||||
obsAdded = false;
|
||||
}
|
||||
|
||||
/* NetworkObserver is null and there are no
|
||||
* conditions to add. Nothing will change by adding
|
||||
* the NetworkObserver component so exit early. */
|
||||
if (!obsAdded && _defaultConditions.Count == 0)
|
||||
return result;
|
||||
|
||||
// If the NetworkObserver component was just added.
|
||||
if (obsAdded)
|
||||
{
|
||||
/* Global nobs do not need a NetworkObserver.
|
||||
* Ultimately, a global NetworkObject is one without
|
||||
* any conditions. */
|
||||
if (isGlobal)
|
||||
return result;
|
||||
// If there are no conditions then there's nothing to add.
|
||||
if (_defaultConditions.Count == 0)
|
||||
return result;
|
||||
/* If here then there not a global networkobject and there are conditions to use.
|
||||
* Since the NetworkObserver is being added fresh, set OverrideType to UseManager
|
||||
* so that the NetworkObserver is populated with the manager conditions. */
|
||||
result.OverrideType = NetworkObserver.ConditionOverrideType.UseManager;
|
||||
}
|
||||
// NetworkObject has a NetworkObserver already on it.
|
||||
else
|
||||
{
|
||||
// If global the NetworkObserver has to be cleared and set to ignore manager.
|
||||
if (isGlobal)
|
||||
{
|
||||
result.ObserverConditionsInternal.Clear();
|
||||
result.OverrideType = NetworkObserver.ConditionOverrideType.IgnoreManager;
|
||||
}
|
||||
}
|
||||
|
||||
// If ignoring manager then use whatever is already configured.
|
||||
if (result.OverrideType == NetworkObserver.ConditionOverrideType.IgnoreManager)
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
// If using manager then replace all with conditions.
|
||||
else if (result.OverrideType == NetworkObserver.ConditionOverrideType.UseManager)
|
||||
{
|
||||
result.ObserverConditionsInternal.Clear();
|
||||
AddMissing(result);
|
||||
}
|
||||
// Adding only new.
|
||||
else if (result.OverrideType == NetworkObserver.ConditionOverrideType.AddMissing)
|
||||
{
|
||||
AddMissing(result);
|
||||
}
|
||||
|
||||
void AddMissing(NetworkObserver networkObserver)
|
||||
{
|
||||
int count = _defaultConditions.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
ObserverCondition oc = _defaultConditions[i];
|
||||
if (!networkObserver.ObserverConditionsInternal.Contains(oc))
|
||||
networkObserver.ObserverConditionsInternal.Add(oc);
|
||||
}
|
||||
}
|
||||
|
||||
result.ConditionsSetByObserverManager = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d331f979d46e8e4a9fc90070c596d44
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bf9191e2e07d29749bca3a1ae44e4bc8, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.7.3R
|
||||
assetPath: Assets/FishNet/Runtime/Managing/Observing/ObserverManager.cs
|
||||
uploadId: 987062
|
||||
Reference in New Issue
Block a user