Мучаюсь с юнити, есть ли эксперты по С#?!
Можно ли как-то сделать динамические изменяемые скрипты 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,
а если учебник открываешь, то там накидывают сложных научных понятий, которые только путают
и отвлекают от сути: всякие полиморфизмы и непонятные другие слова, от которых голова также начинает болеть, а когда самому такая вещь понадобилась, всё иначе воспринимаешь, достаточно просто на код посмотреть!
Не совсем понял цели твоей задачи, но в Unity можно без проблем добавлять/удалять компоненты из кода. см. AddComponent/RemoveComponent
Тогда всё упрощается и не надо городить классы. Возможно, тут задействована магия: зачаровал овцу, теперь она "думает", как корова. =)
Ну допустим я хочу в Орка добавить компонент OrcAI, а в Змею добавить компонент SnakeAI.
Как потом заставить главный скрипт Character, понимать какой скрипт привязан у меня?
В GMS и Lua нет проблем, я просто к переменной могу привязать любую функцию:
MyCurrentAI = MyFunctionAI();
А потом вызывая эту переменную, я мог бы вызывать функцию текущего ИИ, всё просто.
А в C# нельзя так сделать. Отсюда и начались поиски костылей.
Ещё я нарыл идею про интерфейсы в C#, и вроде выглядит прикольно, но ещё не проверял:
То есть непонятно как нанести урон Аватару из этого примера на C# юнити?!
Возможно так или нет?
if (myAvatar.GetComponent<IDamageable>()) myAvatar.Damage(5);
А может я не прав и оно не так работает... Пойду ещё гуглить...
Смотря что ты хочешь с этим делать дальше. Неужели ты хочешь из Character взять свой AI и узнать что это вот прям точно OrcAI ?
Если тебе в Character нужно просто контролировать AI (функция "думать", например), то как тут уже писали - это наследование от одного супер-базового класса с функцией "думать". Либо можно использовать интерфейс. Только в главном AI классе "думать" должна быть virutal, чтобы в OrcAI ты мог её override.
То есть другими словами, я хотел бы получить универсальный доступ к компоненту из другого скрипта:
А вот так в юнити не работает.
Если ты хочешь получить список всех компонентов, то через Гугл выдаёт такое решение: https://answers.unity.com/questions/935586/how-to-get-all-components-in-scene-which-inherit-a.html
Работа через интерфейсы это как с наследованием, только тут ты проверяешь текущий класс, содержит реализацию данного интерфейса, если да, то выполняешь его метод: https://metanit.com/sharp/tutorial/3.49.php
Присвоение функции переменной в C# возможно: https://metanit.com/sharp/tutorial/2.21.php
Ну ещё анонимные методы: https://metanit.com/sharp/tutorial/3.15.php
Большое Спасибо! Хотелось бы только заранее знать какой метод лучше и где меньше всего подводных камней и потенциальных проблем, но возможно пока попробую интерфейсы, а с иеархией классов пока путаюсь.
А кто бы этого не хотел =)
Всё упирается не только в задачу, но и в архитектуру всего проекта, требований к функционалу и расширяемости. Опыт только поможет. Пока не набьёшь шишек, знать не будешь. Если работать в команде, то у кого больше опыта, то им делится и объясняет что к чему, но он видит всю проблему.
Так вроде уже писали несколько раз.
Делай базовый класс, разные ИИ - дочерние от него.
А ссылку используй того же типа, что и базовый класс.
Чтобы таких вопросов не возникало - надо книги читать. Но никто же не читает всякие методики, паттерны и прочее, всем лень, а потом изобретают велосипеды.
А я сколько ни читаю технические книги, не понимаю что там вообще написано. Пока сам лично не попробую пример, и пример желательно должен быть очень короткий в несколько строк + понятный для чего я буду в будущем его использовать. А то книга просто вываливает на тебя что надо учить, но для чего это нужно, часто непонятно, либо сама книга очень скучно написана, чисто для техников, а я как художник не могу долго вчитываться в научные понятия и тупо засыпаю.
По C# могут посоветовать (как уже скидывал ссылки), данный сайт: https://metanit.com/sharp/. Тут и про язык, и про шаблоны. Но шаблоны имеют базовое описание, а про применение в играх можно почитать бесплатную книжку "Шаблоны игрового программирования" Роберт Найстром. Так же по Unity и шаблоны немного рассказывает (когда не рекламирует свои курсы) Роман Сакутин, например: Unity Best Practices, Паттерны. Там много "забавно" контента, в общем на любителя.
И ты тоже, видимо? Методики и паттерны покрывают ту часть ЯП, для которой выработана технология. В основном это ООП. Может уже для АОП придумали, хз. Всего знать не будешь, особенно когда твоя цель - сделать игру, а не погружаться в инструментарий. Зачем нужна Юнити, когда для эффективной работы с ней нужно ещё тащить весь бэкграунд Devops? К тому же, большинство алгоритмов для игр уже хорошо известны и давно реализованы в виде компонент в том же маркете на юнити. Покупай и настривай. На канале того же https://www.youtube.com/c/FatDino прекрасно видно как это работает. Ну если, конечно, есть деньги, и не жалко их тратить на ассеты и компоненты. Если жалко, то лучше гамак использовать XD
SOLID, GRASP, ECS - это всё нужно только в Unity? Ты думаешь, что в GMS этого не надо?
Кстати да, мне обычно попадались книги по шарпу и С++ где очень плотно проходятся по всему ООП, и я долгое время пытался осилить это, но не понимал нужно ли всё учить, зачем так много инфы накидывают про различные виды иерархии, и когда уже будут примеры в рамках игры (то есть зачем я всё это изучаю), а в конечном итоге забил на такие учебники, и стал искать только практические советы для конкретной текущей задачи.
Только его сначала надо купить.
Вообще он теперь бесплатный. То что в нём нельзя экспортнуть EXE, ограничение для дурачков, его можно достать из кэша компиляции, так как по F5 ведь можно сыграть в игру которую ты сейчас делаешь, а значит EXE где-то есть. Хотя по-хорошему для саморазвития никакие внешние EXE не нужны, делаешь себе и делай, вот если релиз уже готов, это другой разговор.
Я так делал на бесплатной версии GM 8.1, чтобы в игре watermark'ов не было.
Только эти "EXE-шники из кэша" перестают запускаться на следующий день. Мне что, часы все время назад переводить? Или может игрок пусть это делает?
Не удивлюсь если в GMS - так же.
Сколько там Desktop в стиме стоит, 1600 pуб? Ты уверен что я на своей игре больше заработаю?
И почему я не делаю игры на GMS я уже говорил - там программировать неудобно.
Вот для Love2D, в обычном редакторе - мне удобно.
Я, может быть, попробую на Гаминатор взять триальную версию GMS и сделать игру на ней, благо триала на 1 месяц хватит, чтобы попробовать ваше хваленое "В современных GMS 2.0 все заебись".
Но заранее уже готов к провалу.
А сейчас всё ещё есть триал и версия за одноразовый платёж? Они же вроде положили на разработчиков подпиську
Для GMS1,2 есть внешний редактор кода, который в чём-то лучше встроенного в IDE.
Жаль, если он действительно лучше встроенного. Кажется, что фишка ГМСа в том, чтобы из него не выходить.
А при чём тут "заработаю"? На хобби тратятся, а не зарабатывают. Можно ещё в магазин для художников или музыкантов пойти и попросить бесплатно краски или гитару, интересно что скажут.
Я не хвалю ГМС2. Всё игры что я хотел бы сделать, прекрасно можно сделать и на ГМ8.1, Студия только для портов на платформы где нормально покупают.