Позади [SerializeField]

Программирование на Юнити.

Позади [SerializeField]

Сообщение MotorHead 18 май 2017, 21:05

Всем добрый день!
Я новичок на этом форуме, в программировании и в изучении Unity.
Обучаюсь сейчас по книге Джозева Хокинга "Юнити в действии".
Есть одна концепция, которую не могу понять - [SerializeField].
Я знаю, что она делает, знаю что такое модификаторы доступа, чем отличается private от public. Я понимаю, что происходит когда пишешь
[SerializeField] private (ClassName) (VariableName);
И чем это отличается от
public (ClassName) (VariableName);
Ответы на эти вопрос есть и в книге и хорошо описаны в посте http://answers.unity3d.com/questions/54 ... 1491129093
НО! есть одна вещь, которую я не понимаю.
Начну с примера.
Когда пишешь [SerializeField] int speed; а в Инспекторе указываешь значение speed = 3, то создается экземпляр класса Int32, по имени speed и его значение равно трем. Это тоже мне понятно.
Ниже представлен код двух классов, которые даются в учебнике для управления графическим интерфейсом пользователя, а именно - открытие спрайта по имени PopUp, который является "Меню настройки"
Первый скрипт UIController присоединен к EmptyObject и по сути является просто контроллером.
Второ скрипт SettingsPopUp присоединен к спрайту PopUp, который и является этим меню.
Синтаксис:
Используется csharp
public class UIController : MonoBehaviour
{
    [SerializeField] private Text scoreLabel;
    [SerializeField] private SettingsPopUp settingsPopUp;

        // Use this for initialization
        void Start ()
    {
        settingsPopUp.Close();
        }
       
        // Update is called once per frame
        void Update ()
    {
        scoreLabel.text = Time.realtimeSinceStartup.ToString();
    }

    public void OnOpenSettings()
    {
        settingsPopUp.Open();
    }
}
 


Синтаксис:
Используется csharp
public class SettingsPopUp : MonoBehaviour
{
        // Use this for initialization
        void Start ()
    {
               
        }
        // Update is called once per frame
        void Update ()
    {
               
    }
    public void Open()
    {
        gameObject.SetActive(true);
    }
    public void Close()
    {
        gameObject.SetActive(false);
    }
}
 


В Unity затем спрайт PopUp перетаскивается в поле Settings Pop Up скрипта UiController
Внимание, вопрос!))
Что за этим стоит?
По идее таким образом мы определяем экземпляр класса SettingsPopUp. Но мы ему присваем спрайт, GameObject, или что?? Я не знаю, у меня нет идей, что за этим стоит и почему так надо поступать. К слову, тоже самое мы делаем с Text scoreLabel и вообще довольно часто такой прием встречается в книге.
Т.е. когда [SerializeField] пишет перед полями типа int, bool, string и т.п. я понимаю
Но когда таким образом мы создаем экземпляр собственного класса, присоединенного к другому объекту - я не понимаю.
Возможно, если кто-нибудь приведет код, как это же самое сделать без [SerializeField] - я пойму.
Прошу помочь разобраться!
Всем спасибо!
MotorHead
UNец
 
Сообщения: 2
Зарегистрирован: 18 май 2017, 20:36

Re: Позади [SerializeField]

Сообщение samana 18 май 2017, 21:21

MotorHead писал(а):По идее таким образом мы определяем экземпляр класса SettingsPopUp. Но мы ему присваем спрайт

Просто Unity упростили задачу переноса в поле инспектора конкретный тип. Вот вам нужно поместить в поле
[SerializeField] private SettingsPopUp settingsPopUp;
ссылку на класс SettingsPopUp, который находится у некого спрайта в сцене. И вы можете просто перенести этот спрайт в то поле и если в спрайте находится SettingsPopUp, то Unity автоматически это распознаёт и заполняет поле ссылкой на этот класс. А если такого класса в спрайте не обнаружится, то поле в инспекторе даже не подсветится, когда попытаетесь поместить туда спрайт.

MotorHead писал(а): если кто-нибудь приведет код, как это же самое сделать без [SerializeField] - я пойму.

Достаточно просто убрать [SerializeField] и заменить там же private на public.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Позади [SerializeField]

Сообщение samana 18 май 2017, 21:31

MotorHead писал(а):Но когда таким образом мы создаем экземпляр собственного класса, присоединенного к другому объекту - я не понимаю.

Это просто ссылки на другие объекты. У вашего спрайта есть компонент SettingsPopUp и он содержит какие-то свои свойства, методы и т.д. и вым можете управлять этим в этом же класса. Но ваш класс-контроллер теперь имеет ссылку на компонент SettingsPopUp спрайта и тоже теперь может управлять им (в ограниченном пространстве конечно, ему доступны только public свойства и методы).
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Позади [SerializeField]

Сообщение MotorHead 19 май 2017, 22:08

А как бы выглядел код, если бы было написано просто private SettingsPopUp settingsPopUp;
Т.е. не было возможности перетаскивать объекты на соответствующее поле в инспекторе. Как, используя только код, сослаться на этот объект?
MotorHead
UNец
 
Сообщения: 2
Зарегистрирован: 18 май 2017, 20:36

Re: Позади [SerializeField]

Сообщение samana 19 май 2017, 22:23

Тогда вам нужно чтобы класс UIController самостоятельно нашел нужный спрайт на сцене, обратился к его с компоненту SettingsPopUp и сохранил на него ссылку, примерно так:
Синтаксис:
Используется csharp
void Start()
{
    settingsPopUp = Find("имяСпрайтаВИерархии").GetComponent<SettingsPopUp>();
}
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10