Мучаюсь с юнити, есть ли эксперты по С#?!
Можно ли как-то сделать динамические изменяемые скрипты AI и Animator?
Допустим я хочу сделать, чтобы можно легко менять у персонажей AI скрипты,
и эти скрипты называются по разному CowAI, DogAI, HumanAI
Можно ли сделать как-то аналог такого псевдокода?AI CurrentAI = GetComponent<Один из моих скриптов AI>();
- 25 октября 2021, 10:10
- 03
Не знаю, как именно в Unity (давно его не трогал и не хочу, может можно динамически присваивать компонент), но снова используем наследование и можно сделать компонент AIEnemy. В нём указать свойство на класс AI. Вызывать методы этого свойства в необходимых местах.
AI - базовый класс с соответствующими методами:
От базового наследуешь классы AICow, AIDog, переопределяя методы. При генерации врагов присваиваешь свойству компонента необходимую ссылку на класс.
То есть надо сделать минимум два класса?
А смогу ли я управлять HumanAI, если по факту у меня только скрипт AI взят через GetComponent?
MyAI = GetComponent<AI>();
Но возможно я просто не понимаю, как это работает...
А что значить "При генерации врагов присваиваешь свойству компонента необходимую ссылку на класс." ?
Я не знаю, можно ли в объект Unity при наличии компонента AI у объекта, как-то менять его "ссылку". Поэтому предлагаю вариант с 3 классами, где один (EnemyAI) является контейнером, в котором есть ссылка на необходимый ИИ:
Я предлагаю такую последовательность:
Update: можно ли MonoBehaviour просто создавать через new я не знаю его реализации. Возможно, просто без него обходиться.
D: Я запутался, но потом когда голова будет лучше соображать попробую перечитать ещё раз.
А вот кстати AI.Update() это получается Update должна быть static?
Опять же, надо лучше знать Unity. Но идея надеюсь стало понятнее.
Ого! Спасибо Огромное! Попробую повозиться с этим примером!
может так проще? вместо абстрактного класса - интерфейс, вместо Start - конструктор
Спасибо! Выглядит вполне читабельно, хотя в обоих вариантах кода смущает Switch, просто если будет около 20-30 поведений врагов, то нужно будет делать длинный список из switch, а если нужно будет расширить список, то придётся вручную заполнять этот статичный список, немножко не удобно, но если варианта лучше не найдётся, то придётся Switch использовать.
Просто я вначале хотел сделать ещё проще, запихать вообще все поведения в один класс, без иерархии:
Но подумал, что это выглядит не очень, и хотел поискать варианта без switch статического списка.
А в итоге может получиться так, что опять к Switch приду)
Операторы switch
Интересно!
Можно создать Map, у которого ключ будет Типом, а значение - экземпляром класса AI
С помощью делегатов?
Я есчесн не помню, но если делегаты - это функции, которые можно пихать в переменные, то да
Согласен. С интерфейсами не знаком alexsilent поэтому использую классы для объяснения
Попробовал сделать на основе этого кода немного иначе по своему, без switch,
и почти получилось, если не считать того что функция Work берётся из BaseAI((
можно ли как-то сделать так, чтобы брать инфу из AICow?
В логах получилось так:
"Start is Okay!" - Start прошёл нормально, и берётся из AICow
"Isn't work! :(" - а функция Work берётся из BaseAI вместо AICow :(
А хотелось бы чтобы обе функции брались из AICow минуя BaseAI, можно ли как-то сделать чтобы
функция Work бралась из AICow класса?
Видимо получается так, что автоматические функции вшитые в юнити работают нормально,
а если я сам вызываю функцию, то её вызывают из базового класса, и это плохо.
Блин, почти получилось, но почти не считается.
Метод Work у тебя не переопределён, а скрыт. Не хватает virtual/override. Смотреть тут.
Большое Спасибо! Теперь функция работает! :3
Наконец-то я понял зачем virtual/override, раньше думал что это какая-то супер сложная тема
и всегда голова болела, когда пытался понять зачем они тут запихали эти override,
а если учебник открываешь, то там накидывают сложных научных понятий, которые только путают
и отвлекают от сути: всякие полиморфизмы и непонятные другие слова, от которых голова также начинает болеть, а когда самому такая вещь понадобилась, всё иначе воспринимаешь, достаточно просто на код посмотреть!