Comment rendre un champ visible (attachable) dans l'inspecteur mais inaccessible par code (privé)?

9

Disons que j'ai une variable nommée buttonde type Buttonqui est bien sûr System.Serializable.

Je veux que cette variable soit assignable via l'inspecteur, donc je le fais public:

public class SomeScript : MonoBehaviour{
    public Button button;
}

Ce qui me donne ça:

entrez la description de l'image ici

Maintenant, je veux garder le code propre et sécurisé (organisé) et il y a une vraie raison pour laquelle je dois préserver l'encapsulation.

Je sais qu'il existe plusieurs façons de récupérer des composants lors de l'exécution, transform.Find("Some/Genius/TypeUnsafe/Path")ou GameObject.Find("3 seconds scene iteration").GetComponent(...).je veux éviter cela.

Comment mélanger une variable private accessavec celle-ci public accessdans l'inspecteur?

Jacob
la source
Pourquoi voulez-vous rendre ce champ "sécurisé" / que voulez-vous dire par là? Notez que je mets cela entre guillemets, car si le code s'exécute sur la machine cliente, le client peut faire à peu près tout ce qu'il veut avec. privaten'est pas vraiment destiné à empêcher un tiers d'accéder à un champ, il est destiné à fournir un moyen de dire "ne regardez pas derrière le rideau ce que je fais vraiment" - c'est-à-dire, c'est surtout un moyen de vous empêcher d'y accéder.
Clockwork-Muse
Ouais, je sais à quoi sert l'encapsulation! : DI a construit une sorte de modèle UI/ API MVC/ MVVMpour une énorme application (un client de jeu en fait) et j'ai dû séparer le UIdu API. J'avais besoin d'attribuer des valeurs via la cause de l'inspecteur simplement - il n'y a pas d'autre moyen. Find()les méthodes ne sont pas sécurisées, et il est plus facile de rassembler les choses en faisant glisser et déposer. Il est vraiment, vraiment difficile de construire un cadre OOP classique Unityet vous devez rechercher des choses hacky comme celle-ci.
Jacob
Gardez à l'esprit que private ne protège pas la variable des autres scripts. Vous pouvez toujours y accéder avec de la réflexion ou une astuce de pointeur
Bálint

Réponses:

19

Vous recherchez l' attribut SerializeField

De la documentation:

Forcer Unity à sérialiser un champ privé.

Vous n'en aurez presque jamais besoin. Lorsque Unity sérialise vos scripts, il ne sérialise que les champs publics. Si, en plus de cela, vous souhaitez également que Unity sérialise l'un de vos champs privés, vous pouvez ajouter l'attribut SerializeField au champ.

Votre code ressemblerait alors à ceci:

public class SomeScript : MonoBehaviour{
    [SerializeField]
    private Button button;
}
Cameron Edwards
la source
6
pour plus de lisibilité, j'écris généralement le tout sur une seule ligne: [SerializeField] private Button button; je trouve cela plus facile à numériser quand il y a un tas de champs dans une rangée. En outre, vissez les documents pour "vous n'en aurez presque jamais besoin"; Je fais ça tout le temps.
jhocking
1

Vous pouvez afficher votre variable privée en ajoutant l' attribut SerializeField avant la variable. Quelque chose comme ça

[SerializeField]
private Button button;

La variable ci-dessus sera affichée à votre inspecteur mais vos autres classes ne pourront pas l'obtenir. Inversement, vous pouvez également masquer votre dossier public dans l'inspecteur via l' attribut HideInInspector . Quelque chose comme ça

[HideInInspector]
public Button button;

Votre variable ci-dessus sera accessible par votre autre script mais elle ne sera pas affichée à l'inspecteur.

Muhammad Faizan Khan
la source