9
\$\begingroup\$

Let's say I have a variable named button of type Button which is of course System.Serializable.

I want that variable to be assignable through the inspector, so I make it public:

public class SomeScript : MonoBehaviour{
    public Button button;
}

Which gives me that:

enter image description here

Now, I want to keep the code clean & secure (organized) and there's a real reason why I need to preserve the encapsulation.

I know that there are multiple ways of retrieving components on runtime like transform.Find("Some/Genius/TypeUnsafe/Path") or GameObject.Find("3 seconds scene iteration").GetComponent(...). I want to avoid that.

How do I mix a variable private access with it's public access in the inspector?

\$\endgroup\$
3
  • \$\begingroup\$ Why do you want to make this field "secure"/what do you mean by that? Note that I put that in quotes, because if code runs on the client machine, the client can do pretty much whatever they want with it. private isn't really intended to prevent a third party from gaining access to a field, it's meant to provide a way to say "don't look behind the curtain at what I'm really doing" - that is, it's mostly a way to keep you from gaining access to it. \$\endgroup\$ Commented Aug 15, 2017 at 15:40
  • \$\begingroup\$ Yeah, I know what encapsulation is for! :D I build some kind of UI/API MVC/MVVM pattern for a huge application (a game client actually) and I had to separate the UI from the API. I needed to assign values through the inspector cause simply - there's no other way. Find() methods are type unsafe, and it's easier to put things together by dragging & dropping. It's really, really hard to build a classic, OOP framework with Unity and you have to look for hacky things like this. \$\endgroup\$
    – Jacob
    Commented Aug 15, 2017 at 16:10
  • \$\begingroup\$ Keep in mind that private doesn't keep the variable secure from other scripts. You cab akways reach it with reflection or some pointer trickery \$\endgroup\$
    – Bálint
    Commented Aug 16, 2017 at 14:01

2 Answers 2

19
\$\begingroup\$

You're looking for the SerializeField Attribute

From the docs:

Force Unity to serialize a private field.

You will almost never need this. When Unity serializes your scripts, it will only serialize public fields. If in addition to that you also want Unity to serialize one of your private fields you can add the SerializeField attribute to the field.

Your code would then look like this:

public class SomeScript : MonoBehaviour{
    [SerializeField]
    private Button button;
}
\$\endgroup\$
1
  • 7
    \$\begingroup\$ for readability I generally write it all on one line: [SerializeField] private Button button; I find that easier to scan when there's a bunch of fields in a row. Also, screw the docs for "you will almost never need this"; I totally do this all the time. \$\endgroup\$
    – jhocking
    Commented Aug 15, 2017 at 15:12
2
\$\begingroup\$

You can show your private variable By adding SerializeField attribute before the variable. Something like this

[SerializeField]
private Button button;

The above variable will be displayed to your inspector but your other classes will unable to get it. Conversely you can also hide your public filed in inspector through HideInInspector attribute. Something like this

[HideInInspector]
public Button button;

Your above variable will be accessible by your other script but it will not be displayed to inspector.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .