Что лучше: ссылка на GameObject или на класс в Unity? - PullRequest
0 голосов
/ 02 ноября 2018

Пример: к GameObject A прикреплен скрипт, который называется MakeItRain. Внутри этого скрипта находится публичный void Drizzle ();

GameObject B также имеет скрипт и хочет, чтобы MakeItRain сделал Drizzle ();

Внутри скрипта GameObject B я могу сделать это:

public GameObject makeitrain;

и затем я должен использовать GetComponent, чтобы добраться до Drizzle (); в моем коде. В инспекторе я помещаю GameObject A в слот makeitrain, и все готово.

Однако я также мог бы сделать это в скрипте GameObject B:

public MakeItRain makeitrain;

, а затем просто наберите makeitrain.Drizzle(); в моем коде скрипта GameObject B. без GetComponent.

В обоих случаях в Инспекторе я должен перетащить GameObject A в слот GameObject B.

Есть ли разница или причина, почему я не должен определенно делать последний вариант? Я понимаю, что первый метод дает мне больше гибкости, потому что я могу вызывать и другие компоненты GameObject A, а не только сценарий. Просто интересно, есть ли какое-либо другое объяснение тому, чтобы не использовать второй метод.

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

Если вы не хотите использовать GetComponent(), вы можете просто использовать SendMeassage(), например,

public Gameobject makeItRain;
void Start(){
    makeitrain.SendMeassage("Drizzle");
}

Другой способ связать скрипт - это использовать FindObjectOfType(), для которого не нужно перетаскивать GameObject в слот, вот пример

void Start(){
    MakeItRain makeitrain = FindObjectOfType("MakeItRain");
}

Также вы можете использовать Gameobject.Find(), чтобы связать GameObject вместо перетаскивания в слот, но я не рекомендую этот способ, это требует больших затрат, поскольку вам нужно найти каждый отдельный GameObject в сцене.

0 голосов
/ 02 ноября 2018

Использование MakeItRain и явное определение типа лучше, чем использование GameObject.

Как заметил @hacksalot, использование MakeItRain предлагает строгую типизацию . Одно из преимуществ этого связано с вашим комментарием:

В обоих случаях в Инспекторе я должен перетащить GameObject A в слот GameObject B.

Если вы явно установите тип общедоступной переменной MakeItRain вместо GameObject, невозможно перетащить GameObject A в слот GameObject B , если GameObject A не имеет скрипт правильного типа. Это дает вам проверку времени компиляции / редактирования, что вы связываетесь с правильным GameObject в Инспекторе редактора Unity .

Также, хотя это и не обязательно, с использованием GameObject ссылок часто поощряет более сложный код , либо из-за ненужной цепочки методов вместе (например, GetComponent) только потому, что тип не был указан, либо потому что это добавляет трения к написанию и использованию вспомогательных методов. Рассмотрим даже простой пример, который читается лучше:

makeitrain.Drizzle()

makeitrain.GetComponent<MakeItRain>().Drizzle()


Я понимаю, что первый метод дает мне больше гибкости, потому что я может вызвать другие компоненты GameObject A, а не только Материал сценария.

Обратите внимание, что у вас все еще есть возможность доступа к GameObject, это просто более многословно (что является одним из недостатков этого подхода):

public MakeItRain makeitrain;

void Start()
{
    makeitrain.gameObject.SetActive(false)
}

Тем не менее, вы, вероятно, в любом случае будете использовать вспомогательные методы (для чего-то большего, чем базовые вызовы) или даже методы-оболочки (которые неудобно писать, но иногда полезны для удобства чтения).

В большинстве случаев преимущества соединения с классом, а не GameObject, перевешивают недостатки.

0 голосов
/ 02 ноября 2018

Ответ зависит от того, требуется ли вам вызвать какую-либо функцию или использовать переменную из сценария MakeItRain.

Если вам не нужно вызывать какую-либо функцию в скрипте MakeItRain или обращаться к каким-либо переменным из нее, то лучше использовать GameObject в качестве ссылки. Кроме того, если вам нужно активировать, деактивировать, повернуть GameObject, а затем использовать GameObject в качестве ссылки.

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

Наконец, при использовании сценария MakeItRain для ссылки на ваш объект вы можете напрямую и легко получить доступ к объекту GameObject, к которому он прикреплен, без использования makeitrain.gameObject. Это не требует использования функции GetComponent.

Просто интересно, есть ли какое-либо другое обоснование для того, чтобы не делать Второй метод.

Причиной является проблема с производительностью из-за обязательного использования функции GetComponent. Лучше использовать его один раз в функции Start или Awake и лучше инициализировать переменную MakeItRain.

Например, это лучше:

public MakeItRain makeitrain;

void Start()
{
    makeitrain = GetComponent<MakeItRain>();
}

void Update()
{
    makeitrain.Drizzle();
}

чем это:

public GameObject makeitrain;

void Update()
{
    makeitrain.GetComponent<MakeItRain>().Drizzle();
}

И его следует использовать, чтобы избежать необходимости искать компонент на собственной стороне каждый кадр .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...