Samuele Sigaudo
Samuele Sigaudo

Reputation: 21

Unity - The same field name is serialized multiple times in the class or its parent class

i have an abstract class from which i derive the various classes i use for the UI, i have a virtual method that i override, but unity shows me this warning when i go to compile (The same field name is serialized multiple times in the class or its parent class), if i declare the isActive variable as protected and i remove the variable isActive from the inherited class this does not happen.

I'm a beginner, the question is more like this, am i implementing this thing the wrong way or is it correct to use isActive as protected?

Base class

[RequireComponent(typeof(CanvasGroup))]
public abstract class UserInterface : MonoBehaviour
{
    [HideInInspector] public CanvasGroup _canvasGroup;

    private bool _isActive;
    public virtual void SetActive(bool active)
    {
        if(_isActive == active) return;

        _isActive = active;
        _canvasGroup.alpha = active ? 1.0f : 0.0f;
        _canvasGroup.interactable = active;
        _canvasGroup.blocksRaycasts = active;
    }
}

Inherited class

    private bool _isActive;
    public override void SetActive(bool active)
    {
        if (_isActive == active) return;

        _isActive = active;
        _messageAnimator.Play(active ? "Message In" : "Message Out");
        _canvasGroup.interactable = active;
        _canvasGroup.blocksRaycasts = active;
    }

Upvotes: 2

Views: 1124

Answers (1)

Paweł Łęgowski
Paweł Łęgowski

Reputation: 830

First of all if you reuse so big chunks of code between parent/child class you are doing something wrong (or maybe you need interface if you expect it might have totally different implementations?). Anyway, try leaving setting _isActive logic to parent class and let child classes just handle state change accordingly like that:

public class UserInterface : MonoBehaviour
{
    [HideInInspector] public CanvasGroup _canvasGroup;
    private bool _isActive;

    public void SetActive(bool active)
    {
        if(_isActive == active) return;

        _isActive = active;
        HandleActiveChanged(_isActive);        
    }

    protected virtual void HandleActiveChanged(bool active)
    {
        _canvasGroup.alpha = active ? 1.0f : 0.0f;
        _canvasGroup.interactable = active;
        _canvasGroup.blocksRaycasts = active;
    }
}

And then the other class just need to override HandleActiveChanged

public class ChildUserInterface : UserInteraface
{
    protected override void HandleActiveChanged(bool active)
    {
        _messageAnimator.Play(active ? "Message In" : "Message Out");
        _canvasGroup.interactable = active;
        _canvasGroup.blocksRaycasts = active;
    }
}

Or else you need to change name of _isActive, this is not C# issue, you should be able to reuse private field names, this is Unity serialization thing.

The approach with interfaces would look like this:

You create interface:

public interface IUserInteraface
{
    void SetActive(bool isActive);
}

and then both of your classes inherit from both MonoBehaviour and IUserInterface

public class UserInterface : MonoBehaviour, IUserInterface
{
    void IUserInterface.SetActive(bool active)
    {
        ...
    }
}

public class SecondUserInterface : MonoBehaviour, IUserInterface
{
    void IUserInterface.SetActive(bool active)
    {
        ...
    }
}

and you then need implemented SetActive independently in both classes like you already did in your code.

Upvotes: -1

Related Questions