Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
Unity Technologies committed Jan 26, 2022
1 parent 36d07fa commit 4818405
Show file tree
Hide file tree
Showing 17 changed files with 403 additions and 39 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

## [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

### Added
Expand All @@ -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 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 network tick value sometimes being duplicated or skipped. (#1614)

### 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)
- 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

Expand Down
4 changes: 0 additions & 4 deletions Editor/NetworkManagerEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public class NetworkManagerEditor : UnityEditor.Editor
private static GUIStyle s_HelpBoxStyle;

// Properties
private SerializedProperty m_DontDestroyOnLoadProperty;
private SerializedProperty m_RunInBackgroundProperty;
private SerializedProperty m_LogLevelProperty;

Expand Down Expand Up @@ -85,7 +84,6 @@ private void Initialize()
m_NetworkManager = (NetworkManager)target;

// Base properties
m_DontDestroyOnLoadProperty = serializedObject.FindProperty(nameof(NetworkManager.DontDestroy));
m_RunInBackgroundProperty = serializedObject.FindProperty(nameof(NetworkManager.RunInBackground));
m_LogLevelProperty = serializedObject.FindProperty(nameof(NetworkManager.LogLevel));
m_NetworkConfigProperty = serializedObject.FindProperty(nameof(NetworkManager.NetworkConfig));
Expand All @@ -112,7 +110,6 @@ private void Initialize()
private void CheckNullProperties()
{
// Base properties
m_DontDestroyOnLoadProperty = serializedObject.FindProperty(nameof(NetworkManager.DontDestroy));
m_RunInBackgroundProperty = serializedObject.FindProperty(nameof(NetworkManager.RunInBackground));
m_LogLevelProperty = serializedObject.FindProperty(nameof(NetworkManager.LogLevel));
m_NetworkConfigProperty = serializedObject.FindProperty(nameof(NetworkManager.NetworkConfig));
Expand Down Expand Up @@ -223,7 +220,6 @@ public override void OnInspectorGUI()
if (!m_NetworkManager.IsServer && !m_NetworkManager.IsClient)
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_DontDestroyOnLoadProperty);
EditorGUILayout.PropertyField(m_RunInBackgroundProperty);
EditorGUILayout.PropertyField(m_LogLevelProperty);
EditorGUILayout.Space();
Expand Down
108 changes: 108 additions & 0 deletions Editor/NetworkManagerHelper.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions Editor/NetworkManagerHelper.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![Forums](https://img.shields.io/badge/unity--forums-multiplayer-blue)](https://forum.unity.com/forums/multiplayer.26/) [![Discord](https://img.shields.io/discord/449263083769036810.svg?label=discord&logo=discord&color=informational)](https://discord.gg/FM8SE9E)
[![Website](https://img.shields.io/badge/docs-website-informational.svg)](https://docs-multiplayer.unity3d.com/) [![Api](https://img.shields.io/badge/docs-api-informational.svg)](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
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.
Expand Down
64 changes: 54 additions & 10 deletions Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,6 @@ public GameObject GetNetworkPrefabOverride(GameObject gameObject)

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>
/// Gets or sets if the application should be set to run in background
/// </summary>
Expand Down Expand Up @@ -490,6 +485,13 @@ private void OnValidate()

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)
{
NetworkLog.LogInfo(nameof(Initialize));
Expand Down Expand Up @@ -941,11 +943,6 @@ public void SetSingleton()

private void OnEnable()
{
if (DontDestroy)
{
DontDestroyOnLoad(gameObject);
}

if (RunInBackground)
{
Application.runInBackground = true;
Expand All @@ -955,13 +952,60 @@ private void OnEnable()
{
SetSingleton();
}

if (!NetworkManagerCheckForParent())
{
DontDestroyOnLoad(gameObject);
}
}

private void Awake()
{
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
private void OnSceneUnloaded(Scene scene)
{
Expand Down
20 changes: 15 additions & 5 deletions Runtime/NetworkVariable/Collections/NetworkList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,18 +272,22 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
{
reader.ReadValueSafe(out int index);
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)
{
OnListChanged(new NetworkListEvent<T>
{
Type = eventType,
Index = index,
Value = value
Value = value,
PreviousValue = previousValue
});
}

Expand All @@ -293,7 +297,8 @@ public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
{
Type = eventType,
Index = index,
Value = value
Value = value,
PreviousValue = previousValue
});
}
}
Expand Down Expand Up @@ -368,7 +373,7 @@ public void Clear()
public bool Contains(T item)
{
int index = NativeArrayExtensions.IndexOf(m_List, item);
return index == -1;
return index != -1;
}

/// <inheritdoc />
Expand Down Expand Up @@ -528,6 +533,11 @@ public enum EventType : byte
/// </summary>
public T Value;

/// <summary>
/// The previous value when "Value" has changed, if available.
/// </summary>
public T PreviousValue;

/// <summary>
/// the index changed, added or removed if available
/// </summary>
Expand Down
16 changes: 2 additions & 14 deletions Runtime/SceneManagement/NetworkSceneManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -565,20 +565,8 @@ internal NetworkSceneManager(NetworkManager networkManager)

GenerateScenesInBuild();

// If NetworkManager has this set to true, then we can get the DDOL (DontDestroyOnLoad) from its GaemObject
if (networkManager.DontDestroy)
{
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);
}
// Since NetworkManager is now always migrated to the DDOL we will use this to get the DDOL scene
DontDestroyOnLoadScene = networkManager.gameObject.scene;

ServerSceneHandleToClientSceneHandle.Add(DontDestroyOnLoadScene.handle, DontDestroyOnLoadScene.handle);
ScenesLoaded.Add(DontDestroyOnLoadScene.handle, DontDestroyOnLoadScene);
Expand Down
5 changes: 5 additions & 0 deletions Runtime/Timing/NetworkTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ private void UpdateCache()
{
double d = m_TimeSec / m_TickInterval;
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);

// This handles negative time, decreases tick by 1 and makes offset positive.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public override void OnNetworkSpawn()

protected override void Update()
{
CanCommitToTransform = IsOwner;
base.Update();
if (NetworkManager.Singleton != null && (NetworkManager.Singleton.IsConnectedClient || NetworkManager.Singleton.IsListening))
{
Expand Down
Loading

0 comments on commit 4818405

Please sign in to comment.