-
Notifications
You must be signed in to change notification settings - Fork 449
Add TargetTransform parameter to NetworkTransform #3436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The recommended way to handle this would be to have something like this:
This way you just need to disable the one Child while the root still can be manipulated and synch'd. |
Yes, but implementing my feature request adds more flexibility that would be extremely useful. This way I don't have to remember this specific hierarchy late in development when I notice things breaking, and can make an adjustment that is easier. By not having a target transform, I am being forced to use a specific hierarchy structure. Just a small vent, but this whole netcode thing where you can't disable the gameobject that it breaks things, desyncs, is just wrong. It goes against the way we code in Unity, and this is the biggest underlying issue that should be fixed. However, at least not forcing us to use a specific hierarchy structure alleviates the problem, even if just a little. |
@marcusx2 The target transform idea was contemplated but there started to be complexities in regards to parenting and it could become an order of operations issue without adding some pretty serious code analyzers and/or "rules" to check for "odd-ball" scenarios... as an example:
In the end the decision was to made to preserve the hierarchy and just use nested NetworkTransforms where the above would just look like:
Generally speaking, we recommend only disabling components and not disabling GameObjects since disabling GameObjects stops MonoBehaviour updates and is the more common way to handle pooled objects. So....it was a decision based on what would be less problematic for all users. However, knowing it can be a pain to try and add specific components and other using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
public class ObjectController : MonoBehaviour
{
public List<Object> Objects;
public Dictionary<Object, PropertyInfo> ObjectProperties = new Dictionary<Object, PropertyInfo>();
private void Awake()
{
var emptyEntries = 0;
foreach (var someObject in Objects)
{
if (someObject == null)
{
emptyEntries++;
continue;
}
var propertyInfo = someObject.GetType().GetProperty("enabled", BindingFlags.Instance | BindingFlags.Public);
if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool))
{
ObjectProperties.Add(someObject, propertyInfo);
}
else
{
Debug.LogWarning($"{name} does not contain a public enable property! (Ignoring)");
}
}
if(emptyEntries > 0)
{
Debug.LogWarning($"{name} has {emptyEntries} emtpy(null) entries in the Objects list!");
}
}
public void SetEnabled(bool isEnabled)
{
foreach (var someObject in Objects)
{
if (ObjectProperties.ContainsKey(someObject))
{
ObjectProperties[someObject].SetValue(someObject, isEnabled);
}
}
}
} I tested it with several different things:
There may be one or two unique scenarios where you could make adjustments to the above and look for a Field as opposed to a property (or the like), but it covers a large portion of the typical types you would want to be able to enable and disable... and you don't need to have any specific property type references (the painful part)... just add it to a network prefab...add an entry to the Objects list and repeat until you have added everything you want to be able to enable or disable. It might help reduce the pain of that process for you. |
As a follow up to the above. using System.Collections.Generic;
using System.Reflection;
using Unity.Netcode;
using UnityEngine;
public class ObjectControllerSynchronized : NetworkBehaviour
{
public bool InitialState;
public List<Object> Objects;
public Dictionary<Object, PropertyInfo> ObjectProperties = new Dictionary<Object, PropertyInfo>();
// Set read and write permissions based on who you want to be the authority of this
private NetworkVariable<bool> m_IsEnabled = new NetworkVariable<bool>();
private void Awake()
{
var emptyEntries = 0;
foreach (var someObject in Objects)
{
if (someObject == null)
{
emptyEntries++;
continue;
}
var propertyInfo = someObject.GetType().GetProperty("enabled", BindingFlags.Instance | BindingFlags.Public);
if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool))
{
ObjectProperties.Add(someObject, propertyInfo);
}
else
{
Debug.LogWarning($"{name} does not contain a public enable property! (Ignoring)");
}
}
if(emptyEntries > 0)
{
Debug.LogWarning($"{name} has {emptyEntries} emtpy(null) entries in the Objects list!");
}
}
/// <summary>
/// Assumes NGO v2.x.x (you can replaced HasAuthority with IsServer, IsOwner, or the like for NGO v1.x.x)
/// </summary>
public override void OnNetworkSpawn()
{
if (HasAuthority)
{
m_IsEnabled.Value = InitialState;
}
base.OnNetworkSpawn();
}
protected override void OnNetworkPostSpawn()
{
if (!HasAuthority)
{
m_IsEnabled.OnValueChanged += OnEnabledChanged;
SetEnabled(m_IsEnabled.Value);
}
base.OnNetworkPostSpawn();
}
public override void OnNetworkDespawn()
{
m_IsEnabled.OnValueChanged -= OnEnabledChanged;
base.OnNetworkDespawn();
}
private void OnEnabledChanged(bool previous, bool current)
{
SetEnabled(current);
}
public void SetEnabled(bool isEnabled)
{
if (HasAuthority)
{
m_IsEnabled.Value = isEnabled;
}
foreach (var someObject in Objects)
{
if (ObjectProperties.ContainsKey(someObject))
{
ObjectProperties[someObject].SetValue(someObject, isEnabled);
}
}
}
} |
Uh oh!
There was an error while loading. Please reload this page.
Is your feature request related to a problem? Please describe.
Yes. Currently, NetworkTransform (and ClientNetworkTransform) desyncs if you disable the gameobject it is attached to. I am currently instead disabling the renderers, etc.
Describe the solution you'd like
If you add a TargetTransform serializable field, I can add the NetworkTransform script to a gameobject I won't disable. Then I can keep enabling/disabling the gameobject with the target transform, which is a lot easier. Right now I always have to attach the NetworkTransform to the gameobject with the transform I want to move, and a lot of scripts like rigidbody, colliders, etc are also attached to it and I can't disable the gameobject because of NetworkTransform, so instead I need to disable the behaviours, renderers, etc.
The text was updated successfully, but these errors were encountered: