Game PlayerObject change fake

Hi, I have been working on a little 2d platformer for a while now and am having some issues with an idea I had. I am trying to change the player game object as a transformation not in the unity sense lol. The two different objects share a control script, and I am faking a parent with the Parent Constraint component to keep them together while switching the renderer, colliders, and animator off. I am using the new Player Input component and can see the bool changing when I run it but the other components do not change just the serialized field _change. My C# and unity knowledge level is armature at best but we all have to start somewhere. If anyone has any ideas on how to get this working I would appreciate the input!

This is the section of the control script I want to handle the change.

[SerializeField]
    private bool _change = false;
    public bool Change
    {
        get
        {
            return _change;
        }

        set
        {
          

            if (_change == true)
            {
                avatar2.GetComponent<ParentConstraint>().enabled = false;
                avatar2.GetComponent<SpriteRenderer>().enabled = true;
                avatar2.GetComponent<CapsuleCollider2D>().enabled = true;
                avatar2.GetComponent<Animator>().enabled = true;

                avatar1.GetComponent<ParentConstraint>().enabled = true;
                avatar1.GetComponent<SpriteRenderer>().enabled = false;
                avatar1.GetComponent<CapsuleCollider2D>().enabled = false;
                avatar1.GetComponent<Animator>().enabled = false;
            }

            else

            {
                avatar1.GetComponent<ParentConstraint>().enabled = false;
                avatar1.GetComponent<SpriteRenderer>().enabled = true;
                avatar1.GetComponent<CapsuleCollider2D>().enabled = true;
                avatar1.GetComponent<Animator>().enabled = true;

                avatar2.GetComponent<ParentConstraint>().enabled = true;
                avatar2.GetComponent<SpriteRenderer>().enabled = false;
                avatar2.GetComponent<CapsuleCollider2D>().enabled = false;
                avatar2.GetComponent<Animator>().enabled = false;
            }
            Change = _change;
        }
    }

    public void change(InputAction.CallbackContext context)
    {
        if (context.started)
        {
            _change = !_change;
        }
       
    }

   
}

Well, what you need to understand is that this:

[SerializeField]
private bool _change = false;

is an actual field that is serialized and shown in the inspector. It consists of actual memory that is part of the object it is defined in. It stores a value true or false.

This:

public bool Change
{
    // ....
}

is a property. A property is NOT a field but it looks like and behaves like a field. A property itself does not store any value and does not occupy memory. So it can not store any value on its own. That’s why properties often have a backing field (like your _change field). A property itself consists just of a pair of methods, one getter and one setter method. Whenever you “read” that property, you actually call the getter method which “returns” the value that the property “seems to have”. When you assign a value to the property you actually call the setter method which gets the new value passed as the special value argument.

What the property does is completely up to you. Currently your setter does not use the “value” that it is set to at all. Also your code currently does not use the property at all. Actually your setter invokes itself at the end which would cause an infinite recursion.

You’re directly using your backing field. Manipulating the backing field has no effect on the property at all.

You probably want a property like this:

    public bool Change
    {
        get
        {
            return _change;
        }
        set
        {
            _change = value;  // actually assign the value that was assigned to the setter to our backing field.
            avatar1.GetComponent<ParentConstraint>().enabled = _change;
            avatar1.GetComponent<SpriteRenderer>().enabled = !_change;
            avatar1.GetComponent<CapsuleCollider2D>().enabled = !_change;
            avatar1.GetComponent<Animator>().enabled = !_change;
            avatar2.GetComponent<ParentConstraint>().enabled = !_change;
            avatar2.GetComponent<SpriteRenderer>().enabled = _change;
            avatar2.GetComponent<CapsuleCollider2D>().enabled = _change;
            avatar2.GetComponent<Animator>().enabled = _change;
        }
    }

Of course this setter would only be called when you actually use it. So instead of doing

_change = !_change;

you should do

Change = !Change;

Though while it may seem quite handy to have a property that does all that when you assign a new value to it, it can be quite cryptic as for another programmer (or yourself in 6 months) it’s not obvious what’s happening. That’s why it’s often better to use an actual method that communicates the intent more clearly. “Change” is also a very bad name for a property or field. So is it true when a “change” happened? It seems that it actually indicates some sort of state which player is active. So please take a bit more time naming things what they actually are or represent.

It is swapping the active player modle. I appreciate the info. I will give your input some thought and have another go at it when I get off work.

Yep looks like I was barking up the wrong tree. lol. Thanks for the help it works great!