Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#if BYPASS_DEFAULT_ENUM_DRAWER && MULTIPLAYER_SERVICES_SDK_INSTALLED
using System.Linq;
#endif
#if UNIFIED_NETCODE
using Unity.NetCode;
using Unity.NetCode.Editor;
#endif
using UnityEditor;
using UnityEngine;

Expand All @@ -23,6 +27,34 @@ public class NetworkObjectEditor : UnityEditor.Editor

private static readonly string[] k_HiddenFields = { "m_Script" };

#if UNIFIED_NETCODE
/// <summary>
/// Register for the GhostAdapter removal event.
/// </summary>
[InitializeOnLoadMethod]
private static void OnApplicationStart()
{
GhostAdapterEditor.OnGhostAdapterPreRemoval = OnGhostAdapterPreRemoval;
}

/// <summary>
/// Callback to remove the GhostBehaviours prior to removing GhostAdapter.
/// </summary>
/// <param name="gameObject">The <see cref="GameObject"/> with the <see cref="GhostAdapter"/> component being removed.</param>
private static void OnGhostAdapterPreRemoval(GameObject gameObject)
{
var ghostBehaviours = gameObject.GetComponentsInChildren<GhostBehaviour>();
for (int i = ghostBehaviours.Length - 1; i >= 0; i--)
{
DestroyImmediate(ghostBehaviours[i], true);
}
var networkObject = gameObject.GetComponent<NetworkObject>();
networkObject.GhostAdapter = null;
networkObject.HasGhost = false;
networkObject.HadBridge = true;
}
#endif

private void Initialize()
{
if (m_Initialized)
Expand Down
51 changes: 44 additions & 7 deletions com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
using Unity.Netcode.Components;
using UnityEditor;
using UnityEngine;
Expand Down Expand Up @@ -94,9 +95,40 @@ public override void OnEnable()
base.OnEnable();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetGUIActive(bool active = true)
{
#if UNIFIED_NETCODE
if (Application.IsPlaying(m_NetworkObject) && m_NetworkObject.HasGhost)
{
GUI.enabled = false;
}
else
{
GUI.enabled = active;
}
#else
GUI.enabled = active;
#endif

}

private NetworkObject m_NetworkObject;

private void DisplayNetworkTransformProperties()
{
var networkTransform = target as NetworkTransform;

#if UNIFIED_NETCODE
m_NetworkObject = networkTransform.GetComponent<NetworkObject>();
var hasGhost = m_NetworkObject.HasGhost;
SetGUIActive();
#else
#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D
var hasGhost = false;
#endif
#endif

EditorGUILayout.LabelField("Axis to Synchronize", EditorStyles.boldLabel);
{
GUILayout.BeginHorizontal();
Expand Down Expand Up @@ -190,7 +222,7 @@ private void DisplayNetworkTransformProperties()
{
networkTransform.UseUnreliableDeltas = false;
}
GUI.enabled = !networkTransform.SwitchTransformSpaceWhenParented;
SetGUIActive(!networkTransform.SwitchTransformSpaceWhenParented);
if (networkTransform.SwitchTransformSpaceWhenParented)
{
EditorGUILayout.BeginHorizontal();
Expand All @@ -202,11 +234,13 @@ private void DisplayNetworkTransformProperties()
{
EditorGUILayout.PropertyField(m_UseUnreliableDeltas);
}
GUI.enabled = true;

SetGUIActive(true);

EditorGUILayout.Space();
EditorGUILayout.LabelField("Configurations", EditorStyles.boldLabel);
GUI.enabled = !networkTransform.UseUnreliableDeltas;

SetGUIActive(!networkTransform.UseUnreliableDeltas);
if (networkTransform.UseUnreliableDeltas)
{
EditorGUILayout.BeginHorizontal();
Expand All @@ -218,7 +252,7 @@ private void DisplayNetworkTransformProperties()
{
EditorGUILayout.PropertyField(m_SwitchTransformSpaceWhenParented);
}
GUI.enabled = true;
SetGUIActive(true);
if (m_SwitchTransformSpaceWhenParented.boolValue)
{
m_TickSyncChildren.boolValue = true;
Expand Down Expand Up @@ -297,20 +331,23 @@ private void DisplayNetworkTransformProperties()

#if COM_UNITY_MODULES_PHYSICS
// if rigidbody is present but network rigidbody is not present
if (networkTransform.TryGetComponent<Rigidbody>(out _) && networkTransform.TryGetComponent<NetworkRigidbody>(out _) == false)
if (hasGhost && networkTransform.TryGetComponent<Rigidbody>(out _) && networkTransform.TryGetComponent<NetworkRigidbody>(out _) == false)
{
EditorGUILayout.HelpBox("This GameObject contains a Rigidbody but no NetworkRigidbody.\n" +
EditorGUILayout.HelpBox("This GameObject contains a Rigidbody but no NetworkRigidbody.\n " +
"Add a NetworkRigidbody component to improve Rigidbody synchronization.", MessageType.Warning);
}
#endif // COM_UNITY_MODULES_PHYSICS

#if COM_UNITY_MODULES_PHYSICS2D
if (networkTransform.TryGetComponent<Rigidbody2D>(out _) && networkTransform.TryGetComponent<NetworkRigidbody2D>(out _) == false)
if (!hasGhost && networkTransform.TryGetComponent<Rigidbody2D>(out _) && networkTransform.TryGetComponent<NetworkRigidbody2D>(out _) == false)
{
EditorGUILayout.HelpBox("This GameObject contains a Rigidbody2D but no NetworkRigidbody2D.\n" +
"Add a NetworkRigidbody2D component to improve Rigidbody2D synchronization.", MessageType.Warning);
}
#endif // COM_UNITY_MODULES_PHYSICS2D
#if UNIFIED_NETCODE
GUI.enabled = true;
#endif
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"Unity.Networking.Transport",
"Unity.Services.Core",
"Unity.Services.Authentication",
"Unity.NetCode"
"Unity.NetCode",
"Unity.NetCode.Editor"
],
"includePlatforms": [
"Editor"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#if UNIFIED_NETCODE
using Unity.NetCode;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;

namespace Unity.Netcode
Expand All @@ -13,31 +10,49 @@ namespace Unity.Netcode
/// <see cref="NetworkObject.SerializedObject"/> the N4E-spawned hybrid prefab instances to the incoming <see cref="CreateObjectMessage"/>
/// specific to the N4E-spawned hybrid prefab instance that has the matching <see cref="NetworkObjectId"/>.
/// </summary>

[DefaultExecutionOrder(GhostAdapterExecutionOrder.ExecutionOrder + 1)]
//BREAK --- Fix this on UNIFIED side 1st
public partial class NetworkObjectBridge : GhostBehaviour
{
// DefaultExecutionOrder
// TODO: Define a const for the value used on GhostAdapter and use that value
// to set the execution order so if it changes on GhostAdapter it updates here.
#if UNITY_EDITOR
[HideInInspector]
[SerializeField]
private bool m_Sorted = false;
private void OnValidate()
{
// TODO-UNIFIED: GhostAdapter must be above all GhostBehaviours in order to assure the GhostAdapter is initialized before any GhostBehaviour.
// This auto-sorting is required because the GhostBehaviours rely on the GhostAdapter.Awake being invoked before any GhostBehaviour.Awake.
if (!m_Sorted && !EditorApplication.isPlaying)
hideFlags = HideFlags.HideInInspector;

var ghostAdapter = GetComponent<GhostAdapter>();
if (ghostAdapter == null)
{
while (UnityEditorInternal.ComponentUtility.MoveComponentUp(this))
{
// Keep moving until it can't go higher
}
var ghostAdapter = gameObject.GetComponent<GhostAdapter>();
// Now move the GhostAdapter to the top so it is above NetworkObjectBridge
while (ghostAdapter != null && UnityEditorInternal.ComponentUtility.MoveComponentUp(ghostAdapter))
return;
}

// Start users with just interpolation (they can adjust this if they want prediction)
// to make the initial transition less problematic for users.
ghostAdapter.SupportedGhostModes = GhostModeMask.Interpolated;

#if COM_UNITY_MODULES_PHYSICS
var rigidBody = GetComponent<Rigidbody>();
var ghostRigidBody = GetComponent<GhostRigidbody>();
if (rigidBody != null)
{
// This must be enabled when replicating the rigid body.

ghostAdapter.SingleWorldHostInterpolationSmoothing = SingleWorldHostInterpolationMode.Interpolate;
// TODO: Currently, this is added only if you enable replication of the rigid body.
// There is a bug where if you don't add this component it doesn't synchronize the transform.
// Remove this once the issue is resolved.
if (ghostRigidBody == null)
{
// Keep moving until it can't go higher
gameObject.AddComponent<GhostRigidbody>();
}

m_Sorted = true;
}
#endif
#if COM_UNITY_MODULES_PHYSICS2D
// TODO: Fill out a similar script as above but for the 2D version
#endif
}
#endif

Expand Down Expand Up @@ -67,6 +82,11 @@ internal void HybridParentUpdate(Vector3 scale)
//Debug.Log($"---- New LT: {transform.localPosition} | {transform.localRotation}");
Ghost.ApplyPostTransformMatrixScale(scale);
}

internal void ApplyScale(Vector3 scale)
{
Ghost.ApplyPostTransformMatrixScale(scale);
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,6 @@ public override bool Initialize(string defaultWorldName)
}

networkManager.NetcodeWorld = (NetcodeWorld)LastCreatedWorld;
#if UNIFIED_NGO_REGISTERS_PREFABS
if (networkManager.NetworkConfig.Prefabs.HasPendingGhostPrefabs)
{
if (networkManager.LogLevel <= LogLevel.Developer)
{
NetworkLog.LogInfo($"[{nameof(UnifiedBootstrap)}] Registering hybrid prefabs...");
}
networkManager.NetworkConfig.Prefabs.RegisterGhostPrefabs(networkManager);
}
#endif
}
else
{
Expand Down
Loading