NetworkVariables fail to initialize for inherited ancestor classes

example:

public class A : NetworkBehavior {
NetworkVariable someValA = new();
}

public class B : class A {
NetworkVariable someValB = new();
}

When the NetworkBehavior Initializes variables, it don’t check the nested classes.

var sortedFields = GetFieldInfoForType(GetType());
            for (int i = 0; i < sortedFields.Length; i++)
            {
                var fieldType = sortedFields[i].FieldType;
                if (fieldType.IsSubclassOf(typeof(NetworkVariableBase)))
                {
                    var instance = (NetworkVariableBase)sortedFields[i].GetValue(this);

                    if (instance == null)
                    {
                        throw new Exception($"{GetType().FullName}.{sortedFields[i].Name} cannot be null. All {nameof(NetworkVariableBase)} instances must be initialized.");
                    }
                   
                    instance.Initialize(this);

                    var instanceNameProperty = fieldType.GetProperty(nameof(NetworkVariableBase.Name));
                    var sanitizedVariableName = sortedFields[i].Name.Replace("<", string.Empty).Replace(">k__BackingField", string.Empty);
                    instanceNameProperty?.SetValue(instance, sanitizedVariableName);

                    NetworkVariableFields.Add(instance);
                }
            }

The “GetType” is getting the reflected fields for just that type. If there’s an inheritance structure, it won’t get the other classes between the Type and NetworkBehavior.

I solved it by making a while loop and iterating up the class hierarchy until the NetworkBehavior class is reached:

var curType = GetType();
            while (curType != typeof(NetworkBehaviour))
            {
                var sortedFields = GetFieldInfoForType(curType);
                for (int i = 0; i < sortedFields.Length; i++)
                {
                    var fieldType = sortedFields[i].FieldType;
                    if (fieldType.IsSubclassOf(typeof(NetworkVariableBase)))
                    {
                        var instance = (NetworkVariableBase)sortedFields[i].GetValue(this);

                        if (instance == null)
                        {
                            throw new Exception($"{GetType().FullName}.{sortedFields[i].Name} cannot be null. All {nameof(NetworkVariableBase)} instances must be initialized.");
                        }

                        instance.Initialize(this);

                        Debug.Log($"InitializeVariables {name} {curType} - {instance}");

                        var instanceNameProperty = fieldType.GetProperty(nameof(NetworkVariableBase.Name));
                        var sanitizedVariableName = sortedFields[i].Name.Replace("<", string.Empty).Replace(">k__BackingField", string.Empty);
                        instanceNameProperty?.SetValue(instance, sanitizedVariableName);

                        NetworkVariableFields.Add(instance);
                    }
                }

                curType = curType.BaseType;
            }

Hi @KingKRoecks , thanks for highlighting the issue and sharing the code. Would it be possible for you to open a bug report here? In this way, the team behind Netcode For GameObject will be able to prioritize your fix, and you’ll be automatically updated about its status.