Почему я должен ссылаться на компоненты при запуске, но объявлять переменные ни в коем случае? - PullRequest
1 голос
/ 21 февраля 2020

Новый для c# и единства. Я не понимаю, почему нужно объявлять переменные в другом месте, чем ссылки на компоненты. Я последовал учебник , чтобы попасть сюда.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sheep : MonoBehaviour
{
    public float runSpeed;
    public float gotHayDestroyDelay;
    private bool hitByHay;

    public float dropDestroyDelay;
    private Collider myCollider; // variables declared here
    private Rigidbody myRigidbody; // and here

    // Start is called before the first frame update
    void Start()
    {
        myCollider = GetComponent<Collider>(); // but set here
        myRigidbody = GetComponent<Rigidbody>(); // and here
    }

    // void Update and some more things here
}

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Вы определяете класс. Когда вы объявляете переменную, вы говорите «A Sheep имеет этот атрибут», но вы не обязательно сообщаете ему, что это за атрибут или что Sheep делает с атрибутом.

В функции Start() в Unity вы даете MonoBehaviour (класс, из которого происходит ваш Sheep; не беспокойтесь слишком о том, как это работает на ранних этапах), инструкции для чего делать правильно, когда объект начинает существовать. В этом случае первое, что вы делаете, это находите ваш коллайдер и ваше твердое тело, чтобы в других функциях (например, Update()) вы знали, что такое myCollider и myRigidbody.

Надеюсь, это поможет , Вы сказали, что вы новичок, поэтому я старался изо всех сил к ELI5.

0 голосов
/ 21 февраля 2020

Кажется, что это гибрид новизны Unity и самого C#. Давайте разберемся с этим:

Наследование

Когда вы пишете сценарий Unity, вы обычно пишете класс C#. Этот класс и вся его информация содержится в коротких (фигурных) фигурных скобках "{" и "}". Однако этот класс также может наследовать от другого класса. Рассмотрите наследование как использование шаблона. Monobehaviour - это определенный в Unity класс, который имеет набор полей, свойств и методов, уже созданных, например, «Update ()», «Start ()», «gameObject» и т. Д. c. Когда вы наследуете от MonoBehaviour, вы на самом деле говорите «использовать шаблон MonoBehaviour».

Так что в следующем коде уже есть много полей / методов, доступных для него из наследования MonoBehaviour, даже если вы не написали ни одного себя:

public class NewScript : MonoBehaviour
{
}

Поля уровня класса

Поле - это то, что вы видите, когда вы "объявляете" переменную:

float numA = 100;

Как вы можете видеть выше код, я могу присвоить значение полю, когда оно объявлено. Это объявление происходит, как только класс создается. В этом случае присвоение объявленной переменной происходит сразу после объявления. Если бы я попытался объявить свое поле с данными из другого класса, а другой класс еще не был создан, он потерпел бы неудачу.

Unity Engine и MonoBehaviour

Теперь, когда мы установили что в вашем классе все происходит "под прикрытием" с MonoBehaviour и что объявления полей уровня класса происходят немедленно, мы можем понять суть вещей:

Вот упрощение того, как запускается программа Unity:

  1. Все GameObjects созданы, их Компоненты инициализированы, а их сценарии созданы.
  2. Все Компоненты запускают Awake ().
  3. Все Компоненты запускают Start ().
  4. Начинается игровой цикл (Update, FixedUpdate, LateUpdate и т. Д. c.).

Обратите внимание, что некоторые объекты GameObject и Компоненты могут создаваться раньше других. Если вы попытаетесь вызвать GetComponent для GameObject до создания другого компонента, произойдет сбой. Вот почему вы не можете вызывать GetComponent на этапе конструктора, когда ваши поля объявлены.

Альтернатива

Unity позволяет сериализовать поля в монобихе, отображая их в инспекторе. Вместо этого вы можете написать декларации полей с заголовком [SerializeField] (или сделать ваши поля общедоступными) и перетащить в них компоненты в инспекторе:

    [SerializeField] private Collider myCollider; // variables declared here
    [SerializeField] private Rigidbody myRigidbody; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...