com.unity.netcode.gameobjects@1.0.0-pre.5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). ## [1.0.0-pre.5] - 2022-01-26 ### Added - Added `PreviousValue` in `NetworkListEvent`, when `Value` has changed (#1528) ### Changed - NetworkManager's GameObject is no longer allowed to be nested under one or more GameObject(s).(#1484) - NetworkManager DontDestroy property was removed and now NetworkManager always is migrated into the DontDestroyOnLoad scene. (#1484) ### Fixed - Fixed network tick value sometimes being duplicated or skipped. (#1614) - Fixed The ClientNetworkTransform sample script to allow for owner changes at runtime. (#1606)
This commit is contained in:
19
CHANGELOG.md
19
CHANGELOG.md
@@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|||||||
|
|
||||||
Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).
|
Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).
|
||||||
|
|
||||||
|
## [1.0.0-pre.5] - 2022-01-26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added `PreviousValue` in `NetworkListEvent`, when `Value` has changed (#1528)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- NetworkManager's GameObject is no longer allowed to be nested under one or more GameObject(s).(#1484)
|
||||||
|
- NetworkManager DontDestroy property was removed and now NetworkManager always is migrated into the DontDestroyOnLoad scene. (#1484)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed network tick value sometimes being duplicated or skipped. (#1614)
|
||||||
|
- Fixed The ClientNetworkTransform sample script to allow for owner changes at runtime. (#1606)
|
||||||
|
|
||||||
## [1.0.0-pre.4] - 2021-01-04
|
## [1.0.0-pre.4] - 2021-01-04
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -29,10 +45,13 @@ Additional documentation and release notes are available at [Multiplayer Documen
|
|||||||
- Fixed KeyNotFound exception when removing ownership of a newly spawned NetworkObject that is already owned by the server. (#1500)
|
- Fixed KeyNotFound exception when removing ownership of a newly spawned NetworkObject that is already owned by the server. (#1500)
|
||||||
- Fixed NetworkManager.LocalClient not being set when starting as a host. (#1511)
|
- Fixed NetworkManager.LocalClient not being set when starting as a host. (#1511)
|
||||||
- Fixed a few memory leak cases when shutting down NetworkManager during Incoming Message Queue processing. (#1323)
|
- Fixed a few memory leak cases when shutting down NetworkManager during Incoming Message Queue processing. (#1323)
|
||||||
|
- Fixed network tick value sometimes being duplicated or skipped. (#1614)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- The SDK no longer limits message size to 64k. (The transport may still impose its own limits, but the SDK no longer does.) (#1384)
|
- The SDK no longer limits message size to 64k. (The transport may still impose its own limits, but the SDK no longer does.) (#1384)
|
||||||
- Updated com.unity.collections to 1.1.0 (#1451)
|
- Updated com.unity.collections to 1.1.0 (#1451)
|
||||||
|
- NetworkManager's GameObject is no longer allowed to be nested under one or more GameObject(s).(#1484)
|
||||||
|
- NetworkManager DontDestroy property was removed and now NetworkManager always is migrated into the DontDestroyOnLoad scene. (#1484)
|
||||||
|
|
||||||
## [1.0.0-pre.3] - 2021-10-22
|
## [1.0.0-pre.3] - 2021-10-22
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ namespace Unity.Netcode.Editor
|
|||||||
private static GUIStyle s_HelpBoxStyle;
|
private static GUIStyle s_HelpBoxStyle;
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
private SerializedProperty m_DontDestroyOnLoadProperty;
|
|
||||||
private SerializedProperty m_RunInBackgroundProperty;
|
private SerializedProperty m_RunInBackgroundProperty;
|
||||||
private SerializedProperty m_LogLevelProperty;
|
private SerializedProperty m_LogLevelProperty;
|
||||||
|
|
||||||
@@ -85,7 +84,6 @@ namespace Unity.Netcode.Editor
|
|||||||
m_NetworkManager = (NetworkManager)target;
|
m_NetworkManager = (NetworkManager)target;
|
||||||
|
|
||||||
// Base properties
|
// Base properties
|
||||||
m_DontDestroyOnLoadProperty = serializedObject.FindProperty(nameof(NetworkManager.DontDestroy));
|
|
||||||
m_RunInBackgroundProperty = serializedObject.FindProperty(nameof(NetworkManager.RunInBackground));
|
m_RunInBackgroundProperty = serializedObject.FindProperty(nameof(NetworkManager.RunInBackground));
|
||||||
m_LogLevelProperty = serializedObject.FindProperty(nameof(NetworkManager.LogLevel));
|
m_LogLevelProperty = serializedObject.FindProperty(nameof(NetworkManager.LogLevel));
|
||||||
m_NetworkConfigProperty = serializedObject.FindProperty(nameof(NetworkManager.NetworkConfig));
|
m_NetworkConfigProperty = serializedObject.FindProperty(nameof(NetworkManager.NetworkConfig));
|
||||||
@@ -112,7 +110,6 @@ namespace Unity.Netcode.Editor
|
|||||||
private void CheckNullProperties()
|
private void CheckNullProperties()
|
||||||
{
|
{
|
||||||
// Base properties
|
// Base properties
|
||||||
m_DontDestroyOnLoadProperty = serializedObject.FindProperty(nameof(NetworkManager.DontDestroy));
|
|
||||||
m_RunInBackgroundProperty = serializedObject.FindProperty(nameof(NetworkManager.RunInBackground));
|
m_RunInBackgroundProperty = serializedObject.FindProperty(nameof(NetworkManager.RunInBackground));
|
||||||
m_LogLevelProperty = serializedObject.FindProperty(nameof(NetworkManager.LogLevel));
|
m_LogLevelProperty = serializedObject.FindProperty(nameof(NetworkManager.LogLevel));
|
||||||
m_NetworkConfigProperty = serializedObject.FindProperty(nameof(NetworkManager.NetworkConfig));
|
m_NetworkConfigProperty = serializedObject.FindProperty(nameof(NetworkManager.NetworkConfig));
|
||||||
@@ -223,7 +220,6 @@ namespace Unity.Netcode.Editor
|
|||||||
if (!m_NetworkManager.IsServer && !m_NetworkManager.IsClient)
|
if (!m_NetworkManager.IsServer && !m_NetworkManager.IsClient)
|
||||||
{
|
{
|
||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
EditorGUILayout.PropertyField(m_DontDestroyOnLoadProperty);
|
|
||||||
EditorGUILayout.PropertyField(m_RunInBackgroundProperty);
|
EditorGUILayout.PropertyField(m_RunInBackgroundProperty);
|
||||||
EditorGUILayout.PropertyField(m_LogLevelProperty);
|
EditorGUILayout.PropertyField(m_LogLevelProperty);
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
|
|||||||
108
Editor/NetworkManagerHelper.cs
Normal file
108
Editor/NetworkManagerHelper.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace Unity.Netcode.Editor
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
/// <summary>
|
||||||
|
/// Specialized editor specific NetworkManager code
|
||||||
|
/// </summary>
|
||||||
|
public class NetworkManagerHelper : NetworkManager.INetworkManagerHelper
|
||||||
|
{
|
||||||
|
internal static NetworkManagerHelper Singleton;
|
||||||
|
|
||||||
|
// This is primarily to handle multiInstance scenarios where more than 1 NetworkManager could exist
|
||||||
|
private static Dictionary<NetworkManager, Transform> s_LastKnownNetworkManagerParents = new Dictionary<NetworkManager, Transform>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the singleton instance and registers for:
|
||||||
|
/// Hierarchy changed notification: to notify the user when they nest a NetworkManager
|
||||||
|
/// Play mode state change notification: to capture when entering or exiting play mode (currently only exiting)
|
||||||
|
/// </summary>
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
private static void InitializeOnload()
|
||||||
|
{
|
||||||
|
Singleton = new NetworkManagerHelper();
|
||||||
|
NetworkManager.NetworkManagerHelper = Singleton;
|
||||||
|
|
||||||
|
EditorApplication.playModeStateChanged -= EditorApplication_playModeStateChanged;
|
||||||
|
EditorApplication.hierarchyChanged -= EditorApplication_hierarchyChanged;
|
||||||
|
|
||||||
|
EditorApplication.playModeStateChanged += EditorApplication_playModeStateChanged;
|
||||||
|
EditorApplication.hierarchyChanged += EditorApplication_hierarchyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EditorApplication_playModeStateChanged(PlayModeStateChange playModeStateChange)
|
||||||
|
{
|
||||||
|
switch (playModeStateChange)
|
||||||
|
{
|
||||||
|
case PlayModeStateChange.ExitingEditMode:
|
||||||
|
{
|
||||||
|
s_LastKnownNetworkManagerParents.Clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EditorApplication_hierarchyChanged()
|
||||||
|
{
|
||||||
|
var allNetworkManagers = Resources.FindObjectsOfTypeAll<NetworkManager>();
|
||||||
|
foreach (var networkManager in allNetworkManagers)
|
||||||
|
{
|
||||||
|
networkManager.NetworkManagerCheckForParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles notifying the user, via display dialog window, that they have nested a NetworkManager.
|
||||||
|
/// When in edit mode it provides the option to automatically fix the issue
|
||||||
|
/// When in play mode it just notifies the user when entering play mode as well as when the user
|
||||||
|
/// tries to start a network session while a NetworkManager is still nested.
|
||||||
|
/// </summary>
|
||||||
|
public bool NotifyUserOfNestedNetworkManager(NetworkManager networkManager, bool ignoreNetworkManagerCache = false, bool editorTest = false)
|
||||||
|
{
|
||||||
|
var gameObject = networkManager.gameObject;
|
||||||
|
var transform = networkManager.transform;
|
||||||
|
var isParented = transform.root != transform;
|
||||||
|
|
||||||
|
var message = NetworkManager.GenerateNestedNetworkManagerMessage(transform);
|
||||||
|
if (s_LastKnownNetworkManagerParents.ContainsKey(networkManager) && !ignoreNetworkManagerCache)
|
||||||
|
{
|
||||||
|
// If we have already notified the user, then don't notify them again
|
||||||
|
if (s_LastKnownNetworkManagerParents[networkManager] == transform.root)
|
||||||
|
{
|
||||||
|
return isParented;
|
||||||
|
}
|
||||||
|
else // If we are no longer a child, then we can remove ourself from this list
|
||||||
|
if (transform.root == gameObject.transform)
|
||||||
|
{
|
||||||
|
s_LastKnownNetworkManagerParents.Remove(networkManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!EditorApplication.isUpdating && isParented)
|
||||||
|
{
|
||||||
|
if (!EditorApplication.isPlaying && !editorTest)
|
||||||
|
{
|
||||||
|
message += $"Click 'Auto-Fix' to automatically remove it from {transform.root.gameObject.name} or 'Manual-Fix' to fix it yourself in the hierarchy view.";
|
||||||
|
if (EditorUtility.DisplayDialog("Invalid Nested NetworkManager", message, "Auto-Fix", "Manual-Fix"))
|
||||||
|
{
|
||||||
|
transform.parent = null;
|
||||||
|
isParented = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s_LastKnownNetworkManagerParents.ContainsKey(networkManager) && isParented)
|
||||||
|
{
|
||||||
|
s_LastKnownNetworkManagerParents.Add(networkManager, networkManager.transform.root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isParented;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
11
Editor/NetworkManagerHelper.cs.meta
Normal file
11
Editor/NetworkManagerHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b26b53dc28ae1b5488bbbecc3e499bbc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
[](https://forum.unity.com/forums/multiplayer.26/) [](https://discord.gg/FM8SE9E)
|
[](https://forum.unity.com/forums/multiplayer.26/) [](https://discord.gg/FM8SE9E)
|
||||||
[](https://docs-multiplayer.unity3d.com/) [](https://docs-multiplayer.unity3d.com/docs/mlapi-api/introduction)
|
[](https://docs-multiplayer.unity3d.com/) [](https://docs-multiplayer.unity3d.com/docs/mlapi-api/introduction)
|
||||||
|
|
||||||
Netcode for GameObjects provides networking capabilities to GameObject & MonoBehaviour Unity workflows. The framework is interoperable with many low-level transports, including the official [Unity Transport Package](https://docs.unity3d.com/Packages/com.unity.transport@1.0/manual/index.html).
|
Netcode for GameObjects provides networking capabilities to GameObject & MonoBehaviour Unity workflows. The framework is interoperable with many low-level transports, including the official [Unity Transport Package](https://docs-multiplayer.unity3d.com/transport/1.0.0/introduction).
|
||||||
|
|
||||||
### Getting Started
|
### Getting Started
|
||||||
Visit the [Multiplayer Docs Site](https://docs-multiplayer.unity3d.com/) for package & API documentation, as well as information about several samples which leverage the Netcode for GameObjects package.
|
Visit the [Multiplayer Docs Site](https://docs-multiplayer.unity3d.com/) for package & API documentation, as well as information about several samples which leverage the Netcode for GameObjects package.
|
||||||
|
|||||||
@@ -197,11 +197,6 @@ namespace Unity.Netcode
|
|||||||
|
|
||||||
public NetworkTime ServerTime => NetworkTickSystem?.ServerTime ?? default;
|
public NetworkTime ServerTime => NetworkTickSystem?.ServerTime ?? default;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets if the NetworkManager should be marked as DontDestroyOnLoad
|
|
||||||
/// </summary>
|
|
||||||
[HideInInspector] public bool DontDestroy = true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets if the application should be set to run in background
|
/// Gets or sets if the application should be set to run in background
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -490,6 +485,13 @@ namespace Unity.Netcode
|
|||||||
|
|
||||||
private void Initialize(bool server)
|
private void Initialize(bool server)
|
||||||
{
|
{
|
||||||
|
// Don't allow the user to start a network session if the NetworkManager is
|
||||||
|
// still parented under another GameObject
|
||||||
|
if (NetworkManagerCheckForParent(true))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
|
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
|
||||||
{
|
{
|
||||||
NetworkLog.LogInfo(nameof(Initialize));
|
NetworkLog.LogInfo(nameof(Initialize));
|
||||||
@@ -941,11 +943,6 @@ namespace Unity.Netcode
|
|||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
if (DontDestroy)
|
|
||||||
{
|
|
||||||
DontDestroyOnLoad(gameObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RunInBackground)
|
if (RunInBackground)
|
||||||
{
|
{
|
||||||
Application.runInBackground = true;
|
Application.runInBackground = true;
|
||||||
@@ -955,6 +952,11 @@ namespace Unity.Netcode
|
|||||||
{
|
{
|
||||||
SetSingleton();
|
SetSingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!NetworkManagerCheckForParent())
|
||||||
|
{
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
@@ -962,6 +964,48 @@ namespace Unity.Netcode
|
|||||||
UnityEngine.SceneManagement.SceneManager.sceneUnloaded += OnSceneUnloaded;
|
UnityEngine.SceneManagement.SceneManager.sceneUnloaded += OnSceneUnloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle runtime detection for parenting the NetworkManager's GameObject under another GameObject
|
||||||
|
/// </summary>
|
||||||
|
private void OnTransformParentChanged()
|
||||||
|
{
|
||||||
|
NetworkManagerCheckForParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the NetworkManager's GameObject is parented under another GameObject and
|
||||||
|
/// notifies the user that this is not allowed for the NetworkManager.
|
||||||
|
/// </summary>
|
||||||
|
internal bool NetworkManagerCheckForParent(bool ignoreNetworkManagerCache = false)
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
var isParented = NetworkManagerHelper.NotifyUserOfNestedNetworkManager(this, ignoreNetworkManagerCache);
|
||||||
|
#else
|
||||||
|
var isParented = transform.root != transform;
|
||||||
|
if (isParented)
|
||||||
|
{
|
||||||
|
throw new Exception(GenerateNestedNetworkManagerMessage(transform));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return isParented;
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal string GenerateNestedNetworkManagerMessage(Transform transform)
|
||||||
|
{
|
||||||
|
return $"{transform.name} is nested under {transform.root.name}. NetworkManager cannot be nested.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
static internal INetworkManagerHelper NetworkManagerHelper;
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for NetworkManagerHelper
|
||||||
|
/// </summary>
|
||||||
|
internal interface INetworkManagerHelper
|
||||||
|
{
|
||||||
|
bool NotifyUserOfNestedNetworkManager(NetworkManager networkManager, bool ignoreNetworkManagerCache = false, bool editorTest = false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Ensures that the NetworkManager is cleaned up before OnDestroy is run on NetworkObjects and NetworkBehaviours when unloading a scene with a NetworkManager
|
// Ensures that the NetworkManager is cleaned up before OnDestroy is run on NetworkObjects and NetworkBehaviours when unloading a scene with a NetworkManager
|
||||||
private void OnSceneUnloaded(Scene scene)
|
private void OnSceneUnloaded(Scene scene)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -272,18 +272,22 @@ namespace Unity.Netcode
|
|||||||
{
|
{
|
||||||
reader.ReadValueSafe(out int index);
|
reader.ReadValueSafe(out int index);
|
||||||
reader.ReadValueSafe(out T value);
|
reader.ReadValueSafe(out T value);
|
||||||
if (index < m_List.Length)
|
if (index >= m_List.Length)
|
||||||
{
|
{
|
||||||
m_List[index] = value;
|
throw new Exception("Shouldn't be here, index is higher than list length");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var previousValue = m_List[index];
|
||||||
|
m_List[index] = value;
|
||||||
|
|
||||||
if (OnListChanged != null)
|
if (OnListChanged != null)
|
||||||
{
|
{
|
||||||
OnListChanged(new NetworkListEvent<T>
|
OnListChanged(new NetworkListEvent<T>
|
||||||
{
|
{
|
||||||
Type = eventType,
|
Type = eventType,
|
||||||
Index = index,
|
Index = index,
|
||||||
Value = value
|
Value = value,
|
||||||
|
PreviousValue = previousValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +297,8 @@ namespace Unity.Netcode
|
|||||||
{
|
{
|
||||||
Type = eventType,
|
Type = eventType,
|
||||||
Index = index,
|
Index = index,
|
||||||
Value = value
|
Value = value,
|
||||||
|
PreviousValue = previousValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +373,7 @@ namespace Unity.Netcode
|
|||||||
public bool Contains(T item)
|
public bool Contains(T item)
|
||||||
{
|
{
|
||||||
int index = NativeArrayExtensions.IndexOf(m_List, item);
|
int index = NativeArrayExtensions.IndexOf(m_List, item);
|
||||||
return index == -1;
|
return index != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -528,6 +533,11 @@ namespace Unity.Netcode
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public T Value;
|
public T Value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The previous value when "Value" has changed, if available.
|
||||||
|
/// </summary>
|
||||||
|
public T PreviousValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// the index changed, added or removed if available
|
/// the index changed, added or removed if available
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -565,20 +565,8 @@ namespace Unity.Netcode
|
|||||||
|
|
||||||
GenerateScenesInBuild();
|
GenerateScenesInBuild();
|
||||||
|
|
||||||
// If NetworkManager has this set to true, then we can get the DDOL (DontDestroyOnLoad) from its GaemObject
|
// Since NetworkManager is now always migrated to the DDOL we will use this to get the DDOL scene
|
||||||
if (networkManager.DontDestroy)
|
DontDestroyOnLoadScene = networkManager.gameObject.scene;
|
||||||
{
|
|
||||||
DontDestroyOnLoadScene = networkManager.gameObject.scene;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Otherwise, we have to create a GameObject and move it into the DDOL in order to
|
|
||||||
// register the DDOL scene handle with NetworkSceneManager
|
|
||||||
var myDDOLObject = new GameObject("DDOL-NWSM");
|
|
||||||
UnityEngine.Object.DontDestroyOnLoad(myDDOLObject);
|
|
||||||
DontDestroyOnLoadScene = myDDOLObject.scene;
|
|
||||||
UnityEngine.Object.Destroy(myDDOLObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerSceneHandleToClientSceneHandle.Add(DontDestroyOnLoadScene.handle, DontDestroyOnLoadScene.handle);
|
ServerSceneHandleToClientSceneHandle.Add(DontDestroyOnLoadScene.handle, DontDestroyOnLoadScene.handle);
|
||||||
ScenesLoaded.Add(DontDestroyOnLoadScene.handle, DontDestroyOnLoadScene);
|
ScenesLoaded.Add(DontDestroyOnLoadScene.handle, DontDestroyOnLoadScene);
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ namespace Unity.Netcode
|
|||||||
{
|
{
|
||||||
double d = m_TimeSec / m_TickInterval;
|
double d = m_TimeSec / m_TickInterval;
|
||||||
m_CachedTick = (int)d;
|
m_CachedTick = (int)d;
|
||||||
|
// This check is needed due to double division imprecision of large numbers
|
||||||
|
if ((d - m_CachedTick) >= 0.999999999999)
|
||||||
|
{
|
||||||
|
m_CachedTick++;
|
||||||
|
}
|
||||||
m_CachedTickOffset = ((d - Math.Truncate(d)) * m_TickInterval);
|
m_CachedTickOffset = ((d - Math.Truncate(d)) * m_TickInterval);
|
||||||
|
|
||||||
// This handles negative time, decreases tick by 1 and makes offset positive.
|
// This handles negative time, decreases tick by 1 and makes offset positive.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace Unity.Netcode.Samples
|
|||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
|
CanCommitToTransform = IsOwner;
|
||||||
base.Update();
|
base.Update();
|
||||||
if (NetworkManager.Singleton != null && (NetworkManager.Singleton.IsConnectedClient || NetworkManager.Singleton.IsListening))
|
if (NetworkManager.Singleton != null && (NetworkManager.Singleton.IsConnectedClient || NetworkManager.Singleton.IsListening))
|
||||||
{
|
{
|
||||||
|
|||||||
38
Tests/Editor/NetworkManagerConfigurationTests.cs
Normal file
38
Tests/Editor/NetworkManagerConfigurationTests.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using UnityEngine;
|
||||||
|
using Unity.Netcode.Editor;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
|
||||||
|
namespace Unity.Netcode.EditorTests
|
||||||
|
{
|
||||||
|
public class NetworkManagerConfigurationTests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Does a simple check to make sure the nested network manager will
|
||||||
|
/// notify the user when in the editor. This is just a unit test to
|
||||||
|
/// validate this is functioning
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void NestedNetworkManagerCheck()
|
||||||
|
{
|
||||||
|
var parent = new GameObject("ParentObject");
|
||||||
|
var networkManagerObject = new GameObject(nameof(NestedNetworkManagerCheck));
|
||||||
|
var networkManager = networkManagerObject.AddComponent<NetworkManager>();
|
||||||
|
|
||||||
|
// Make our NetworkManager's GameObject nested
|
||||||
|
networkManagerObject.transform.parent = parent.transform;
|
||||||
|
|
||||||
|
// Pre-generate the error message we are expecting to see
|
||||||
|
var messageToCheck = NetworkManager.GenerateNestedNetworkManagerMessage(networkManagerObject.transform);
|
||||||
|
|
||||||
|
// Trap for the nested NetworkManager exception
|
||||||
|
LogAssert.Expect(LogType.Error, messageToCheck);
|
||||||
|
|
||||||
|
// Since this is an in-editor test, we must force this invocation
|
||||||
|
NetworkManagerHelper.Singleton.NotifyUserOfNestedNetworkManager(networkManager, false, true);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
Object.DestroyImmediate(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Tests/Editor/NetworkManagerConfigurationTests.cs.meta
Normal file
11
Tests/Editor/NetworkManagerConfigurationTests.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9b84044fccbd3cd49908f0efd5719347
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -198,6 +198,39 @@ namespace Unity.Netcode.EditorTests
|
|||||||
Assert.IsTrue(Approximately(startTime.Time, (startTime2 - dif).Time, maxAcceptableTotalOffset));
|
Assert.IsTrue(Approximately(startTime.Time, (startTime2 - dif).Time, maxAcceptableTotalOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void NetworkTickAdvanceTest()
|
||||||
|
{
|
||||||
|
var shortSteps = Enumerable.Repeat(1 / 30f, 1000);
|
||||||
|
NetworkTickAdvanceTestInternal(shortSteps, 30, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkTickSystem m_TickSystem;
|
||||||
|
private NetworkTimeSystem m_TimeSystem;
|
||||||
|
private int m_PreviousTick;
|
||||||
|
|
||||||
|
private void NetworkTickAdvanceTestInternal(IEnumerable<float> steps, uint tickRate, float start, float start2 = 0f)
|
||||||
|
{
|
||||||
|
m_PreviousTick = 0;
|
||||||
|
m_TickSystem = new NetworkTickSystem(tickRate, start, start2);
|
||||||
|
m_TimeSystem = NetworkTimeSystem.ServerTimeSystem();
|
||||||
|
|
||||||
|
m_TickSystem.Tick += TickUpdate;
|
||||||
|
foreach (var step in steps)
|
||||||
|
{
|
||||||
|
m_TimeSystem.Advance(step);
|
||||||
|
m_TickSystem.UpdateTick(m_TimeSystem.LocalTime, m_TimeSystem.ServerTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TickUpdate()
|
||||||
|
{
|
||||||
|
// Make sure our tick is precisely 1 + m_PreviousTick
|
||||||
|
Assert.IsTrue(m_TickSystem.LocalTime.Tick == m_PreviousTick + 1);
|
||||||
|
// Assign the m_PreviousTick value for next tick check
|
||||||
|
m_PreviousTick = m_TickSystem.LocalTime.Tick;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool Approximately(double a, double b, double epsilon = 0.000001d)
|
private static bool Approximately(double a, double b, double epsilon = 0.000001d)
|
||||||
{
|
{
|
||||||
var dif = Math.Abs(a - b);
|
var dif = Math.Abs(a - b);
|
||||||
|
|||||||
37
Tests/Runtime/NestedNetworkManagerTests.cs
Normal file
37
Tests/Runtime/NestedNetworkManagerTests.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.TestTools;
|
||||||
|
using Unity.Netcode;
|
||||||
|
using Unity.Netcode.RuntimeTests;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace TestProject.RuntimeTests
|
||||||
|
{
|
||||||
|
public class NestedNetworkManagerTests
|
||||||
|
{
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator CheckNestedNetworkManager()
|
||||||
|
{
|
||||||
|
var parent = new GameObject("ParentObject");
|
||||||
|
var networkManagerObject = new GameObject(nameof(CheckNestedNetworkManager));
|
||||||
|
|
||||||
|
// Make our NetworkManager's GameObject nested
|
||||||
|
networkManagerObject.transform.parent = parent.transform;
|
||||||
|
|
||||||
|
// Pre-generate the error message we are expecting to see
|
||||||
|
var messageToCheck = NetworkManager.GenerateNestedNetworkManagerMessage(networkManagerObject.transform);
|
||||||
|
var transport = networkManagerObject.AddComponent<SIPTransport>();
|
||||||
|
var networkManager = networkManagerObject.AddComponent<NetworkManager>();
|
||||||
|
networkManager.NetworkConfig = new NetworkConfig() { NetworkTransport = transport };
|
||||||
|
// Trap for the nested NetworkManager exception
|
||||||
|
LogAssert.Expect(LogType.Error, messageToCheck);
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(0.02f);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
Object.Destroy(parent);
|
||||||
|
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Tests/Runtime/NestedNetworkManagerTests.cs.meta
Normal file
11
Tests/Runtime/NestedNetworkManagerTests.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 738f6d8fc9319fe42a986c2f43989642
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -224,8 +224,8 @@ namespace Unity.Netcode.RuntimeTests
|
|||||||
{
|
{
|
||||||
return m_Player1OnServer.TheList.Count == 1 &&
|
return m_Player1OnServer.TheList.Count == 1 &&
|
||||||
m_Player1OnClient1.TheList.Count == 1 &&
|
m_Player1OnClient1.TheList.Count == 1 &&
|
||||||
m_Player1OnServer.TheList.Contains(k_TestKey1) &&
|
m_Player1OnServer.TheList.Contains(k_TestVal1) &&
|
||||||
m_Player1OnClient1.TheList.Contains(k_TestKey1);
|
m_Player1OnClient1.TheList.Contains(k_TestVal1);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -328,6 +328,58 @@ namespace Unity.Netcode.RuntimeTests
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[UnityTest]
|
||||||
|
public IEnumerator NetworkListValueUpdate([Values(true, false)] bool useHost)
|
||||||
|
{
|
||||||
|
m_TestWithHost = useHost;
|
||||||
|
yield return MultiInstanceHelpers.RunAndWaitForCondition(
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
m_Player1OnServer.TheList.Add(k_TestVal1);
|
||||||
|
},
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
return m_Player1OnServer.TheList.Count == 1 &&
|
||||||
|
m_Player1OnClient1.TheList.Count == 1 &&
|
||||||
|
m_Player1OnServer.TheList[0] == k_TestVal1 &&
|
||||||
|
m_Player1OnClient1.TheList[0] == k_TestVal1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var testSucceeded = false;
|
||||||
|
|
||||||
|
void TestValueUpdatedCallback(NetworkListEvent<int> changedEvent)
|
||||||
|
{
|
||||||
|
testSucceeded = changedEvent.PreviousValue == k_TestVal1 &&
|
||||||
|
changedEvent.Value == k_TestVal3;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
yield return MultiInstanceHelpers.RunAndWaitForCondition(
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
m_Player1OnServer.TheList[0] = k_TestVal3;
|
||||||
|
m_Player1OnClient1.TheList.OnListChanged += TestValueUpdatedCallback;
|
||||||
|
},
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
return m_Player1OnServer.TheList.Count == 1 &&
|
||||||
|
m_Player1OnClient1.TheList.Count == 1 &&
|
||||||
|
m_Player1OnServer.TheList[0] == k_TestVal3 &&
|
||||||
|
m_Player1OnClient1.TheList[0] == k_TestVal3;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
m_Player1OnClient1.TheList.OnListChanged -= TestValueUpdatedCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(testSucceeded);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void NetworkListIEnumerator([Values(true, false)] bool useHost)
|
public void NetworkListIEnumerator([Values(true, false)] bool useHost)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "com.unity.netcode.gameobjects",
|
"name": "com.unity.netcode.gameobjects",
|
||||||
"displayName": "Netcode for GameObjects",
|
"displayName": "Netcode for GameObjects",
|
||||||
"description": "Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.",
|
"description": "Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.",
|
||||||
"version": "1.0.0-pre.4",
|
"version": "1.0.0-pre.5",
|
||||||
"unity": "2020.3",
|
"unity": "2020.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"com.unity.modules.animation": "1.0.0",
|
"com.unity.modules.animation": "1.0.0",
|
||||||
@@ -12,12 +12,12 @@
|
|||||||
"com.unity.collections": "1.1.0"
|
"com.unity.collections": "1.1.0"
|
||||||
},
|
},
|
||||||
"upmCi": {
|
"upmCi": {
|
||||||
"footprint": "28fd203207af71c78d6aaba679e94c5ead807529"
|
"footprint": "770504b1f691c766a300b616c1d8106335265f3c"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "https://github.com/Unity-Technologies/com.unity.netcode.gameobjects.git",
|
"url": "https://github.com/Unity-Technologies/com.unity.netcode.gameobjects.git",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"revision": "b14204cd059fb90f4a64319824105619f317d591"
|
"revision": "d1f990d97b80d49ce12fce7357cbd5f6b794ce01"
|
||||||
},
|
},
|
||||||
"samples": [
|
"samples": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user