Является ли хорошей практикой создание класса между моими собственными сценариями и моно-поведением? - PullRequest
1 голос
/ 11 апреля 2019

Итак, я связал CombatController с объектом с именем "godObject".В методе Start() я вызываю функции init() для других классов.Я сделал это, чтобы контролировать порядок инициализации объектов, поскольку, например, контроллер персонажа полагается на инициализацию контроллера сетки.

Быстрая диаграмма:

--------------------   calls 
| CombatController | ----------> CameraController.init(); 
--------------------      |
                          | ---> GridController.init();
                          |
                          | ---> CharacterController.init();

Итак,теперь у меня небольшая проблема.У меня есть несколько свойств, которые мне нужны в каждом контроллере.На данный момент я все привязал к самому боевому контроллеру.Это означает, что в каждом контроллере мне нужно получить экземпляр CombatController через GameObject.Find("godObject).GetComponent<CombatController>().Если честно, я не думаю, что это хороший дизайн.

Моя идея теперь состояла в том, чтобы создать BaseCombatController, который расширяет MonoBehavior, и затем все другие классы, такие как GridController, CharacterController и т. Д., Расширяют BaseCombatController.Это может выглядеть так:

public class BaseCombatController : MonoBehaviour
{
    public GameObject activePlayer;

    public void setActivePlayer(GameObject player) {
        this.activePlayer = player;
    }

    ... more stuff to come ...
}

Таким образом, я могу получить доступ к activePlayer везде без необходимости создавать новый экземпляр CombatController.Однако, я не уверен, что у этого нет возможных побочных эффектов.

Итак, много текста для простого вопроса, это безопасно сделать?

Ответы [ 3 ]

3 голосов
/ 11 апреля 2019

Я все время использую наследование в Unity.Хитрость, как и у вас в вопросе, заключается в том, чтобы ваш базовый класс унаследовал от монобиха.Например:

public class Base Item : Monobehavior 
{
   public string ItemName;
   public int Price;
   public virtual void PickUp(){//pickup logic}
   //Additional functions. Update etc. Make them virtual.
}

Этот класс определяет, что должен делать элемент.Затем в производном классе вы можете изменить и расширить это поведение.

public class Coin : BaseItem
{
    //properties set in the inspector
    public override void PickUp(){//override pickup logic}
}

Я много раз использовал этот шаблон проектирования в течение прошлого года и в настоящее время использую его в розничном продукте.Я бы сказал, пойти на это!Unity, кажется, предпочитает компоненты наследованию, но вы можете легко использовать их вместе друг с другом.

Надеюсь, это поможет!

2 голосов
/ 11 апреля 2019

Насколько я понимаю, это должно быть безопасно. Если вы посмотрите на Unity intern или даже на сценарии Microsoft, они все расширяют / наследуют друг от друга.

Еще одна вещь, которую вы можете попробовать - это использование интерфейсов, вот документация Unity к ним: https://unity3d.com/learn/tutorials/topics/scripting/interfaces, если вы хотите проверить это.

1 голос
/ 12 апреля 2019

Вы правы, что GameObject.Find - чистый запах кода.

Вы можете сделать это через дерево наследования (как обсуждалось ранее) или даже лучше через интерфейсы (как упомянуто Assasin Bot), или (IЯ удивлен, что никто не упоминал об этом раньше) через статические поля (или шаблон Singleton).

Одна вещь, которую нужно добавить из опыта - необходимость вызывать Inits () в определенном порядке - это желтый флаг для вашего дизайна -Я сам был там и обнаружил, что утонул в управлении заказами init.

В качестве общего совета: Unity дает вам два полезных обратных вызова - Awake () и Start ().Если вам нужен Init (), вы, вероятно, не используете эти два, как они были задуманы.

Все Awakes () гарантированно (для объектов acvie) будут запускаться до первого Start (), поэтому всевнутренняя инициализация объекта в Awake () и привязка к внешним объектам в Start ().Если вам нужен более точный контроль - вероятно, вам следует немного упростить дизайн.

Как правило: к концу Awake () все объекты должны иметь свое внутреннее состояние (getcomponents <>, элементы списка и т. Д.) В порядке, но они не должны делать никаких вызовов в зависимости от того, какие другие объекты находятсяготов перед запуском ().Такое разделение обычно очень помогает

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