Jak sprawić, by pole było widoczne (możliwe do dołączenia) w inspektorze, ale niedostępne przez kod (prywatny)?

9

Powiedzmy, że mam zmienną o nazwie buttontype, Buttonktóra jest oczywiście System.Serializable.

Chcę, aby ta zmienna była przypisywalna przez inspektora, więc robię to public:

public class SomeScript : MonoBehaviour{
    public Button button;
}

Co daje mi to:

wprowadź opis zdjęcia tutaj

Teraz chcę, aby kod był czysty i bezpieczny (zorganizowany) i istnieje prawdziwy powód, dla którego muszę zachować enkapsulację.

Wiem, że istnieje wiele sposobów pobierania składników w środowisku wykonawczym, takich jak transform.Find("Some/Genius/TypeUnsafe/Path")lub GameObject.Find("3 seconds scene iteration").GetComponent(...).chcę tego uniknąć.

Jak mieszać zmienną private accessz nią public accessw inspektorze?

Jakub
źródło
Dlaczego chcesz, aby to pole było „bezpieczne” / co przez to rozumiesz? Zauważ, że umieszczam to w cudzysłowie, ponieważ jeśli kod działa na komputerze klienckim, klient może zrobić z nim wszystko, co chce. privatetak naprawdę nie ma na celu uniemożliwiać stronom trzecim uzyskania dostępu do pola, ma na celu dać możliwość powiedzenia: „nie patrz za zasłonę na to, co naprawdę robię” - to w większości sposób uniemożliwić ci dostęp do niego.
Clockwork-Muse,
Tak, wiem po co jest kapsułkowanie! : DI zbudowałem jakiś wzorzec UI/ API MVC/ MVVMdla ogromnej aplikacji (właściwie klienta gry) i musiałem oddzielić UIod API. Musiałem po prostu przypisać wartości przez inspektora, bo po prostu - nie ma innego wyjścia. Find()metody są niebezpieczne dla typu i łatwiej jest łączyć rzeczy poprzez przeciąganie i upuszczanie. Naprawdę, bardzo ciężko jest zbudować klasyczne środowisko OOP Unityi trzeba szukać takich hackerskich rzeczy.
Jakub
Pamiętaj, że private nie chroni zmiennej przed innymi skryptami. Zawsze jeździsz taksówką z odbiciem lub sztuczką wskaźnikową
Bálint

Odpowiedzi:

19

Szukasz atrybutu SerializeField

Z dokumentów:

Zmuś Unity do serializacji prywatnego pola.

Prawie nigdy tego nie będziesz potrzebować. Kiedy Unity serializuje twoje skrypty, serializuje tylko pola publiczne. Jeśli oprócz tego chcesz, aby Unity serializował jedno z twoich prywatnych pól, możesz dodać atrybut SerializeField do pola.

Twój kod wyglądałby wtedy następująco:

public class SomeScript : MonoBehaviour{
    [SerializeField]
    private Button button;
}
Cameron Edwards
źródło
6
dla czytelności piszę to wszystko w jednym wierszu: [SerializeField] private Button button; łatwiej mi skanować, gdy w rzędzie jest kilka pól. Ponadto, przykręć dokumenty dla „prawie nigdy nie będziesz tego potrzebować”; Cały czas to robię.
jhocking
1

Możesz pokazać swoją zmienną prywatną, dodając atrybut SerializeField przed zmienną. Coś takiego

[SerializeField]
private Button button;

Powyższa zmienna zostanie wyświetlona inspektorowi, ale inne klasy nie będą w stanie jej uzyskać. I odwrotnie , możesz również ukryć swoje publiczne dane złożone w inspektorze za pomocą atrybutu HideInInspector . Coś takiego

[HideInInspector]
public Button button;

Powyższa zmienna będzie dostępna dla drugiego skryptu, ale nie będzie wyświetlana inspektorowi.

Muhammad Faizan Khan
źródło