С каким модификатором доступа правильно объявлять GameObject?

Я много раз видел как GameObject объявляют с модификатором доступа public
Но правильно ли это?

Ведь можно использовать [SerializeField] private
(если он конечно используется только внутри класса)

В целом этот вопрос относится не только к GameObject, например также к Image, Transform и другим компонентам.


Ответы (1 шт):

Автор решения: Yaroslav

[SerializeField] private, к всему... вообще.

Считай что модификатор public существует только для классов, их методов, их свойств, структур и т.д. для всего кроме полей класса.

Даже если он используется не только внутри класса, это не значит что кто-то снаружи должен иметь право менять значение поля или выставить в null, после чего посыпятся NullReferenceException.

public class Move : Monobehaviour 
{
    [SerializeField] private int _speed;
    
    public int Speed => _speed; // снаружи только для чтения
    public Vector3 CurrentVector { get; private set; } // снаружи только для чтения
    public Vector3 InputVector { get; set; } // задается снаружи управлением

    private void Update ()
    {
        CurrentVector = MoveVector*_speed;
        transform.position += CurrentVector*Time.deltaTime;
    }
}

Условие простое, что-бы из public в классе ты не сделал, он не перестанет выполнять свои функции и не сойдет с ума, весь смысл. Результат: написав Move. в выпадающем списке не увидишь ничего лишнего, только то с чем можно работать.


public class Aim : MonoBehaviour 
{
    public Transform Target { get; set; }

    public void Update () 
    {
        if (Target != null)
            transform.rotation.SetLookRotation(Target);
    }
}

Класс целится, если есть в кого. Казалось бы можно написать public поле, но нужды в поле нет, ни для сериализации, ни для инспектора, его цель существования runtime постоянно изменяться кем-то снаружи, как InputVector, используй свойство. Хотя автосвойство ({get; set;}) это на самом деле скрытое поле, но все-же, для порядок разделения супа от мух.

В идеале принципы программирования вообще диктуют обращаться одним классам к другим через интерфейсы, а интерфейсы не предполагают полей, только свойства и методы. Это конечно хардкор, интерфейсы не обязательны абсолютно везде, особенно в Unity где они не всегда удобны, но принимающий значения все равно должен получать их через свойства а не поле.

→ Ссылка