Клон контры на Unity3d - часть 3

Очередные четыре ролика готовы к тому, чтобы на них смотрели. Основное внимание в роликах уделено стрельбе. К концу двеннадцатого ролика имеем полностью анимированного персонажа, умеющего стрелять из всех положений.

А ещё, я вывалил проект на гитхаб, и делаю коммиты после каждого записанного видоса.

Кому интересно посмотреть - https://github.com/tyzegt/AlmostContra

Клон контры на Unity3d - часть 3 Программирование, Игры, Разработка игр, Gamedev, Unity, Unity3D, Гифка, Видео, Длиннопост

Часть 9 - Базовая стрельба:

Часть 10 - Стрельба во всех направлениях:

Часть 11 - Анимация стрельбы:

Часть 12 - Стрельба из разных положений:

Лига Разработчиков Видеоигр

6.6K поста22.1K подписчиков

Добавить пост

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Вы смотрите срез комментариев. Показать все
2
Автор поста оценил этот комментарий

Только сейчас дошел до исходников и был удивлен. Многие функции - это ненужный колхоз, если честно:) код можно сократить в 2 раза и читабельность повысить еще в 10. Особенно порадовала функция Animate(), которая вызывается каждый Update(). В играх ААА класса меньше параметров в контроллерах аниматоров чем у Вас. и нафиг использовать bool, если есть trigger? А вообще, достоточно передавать в аниматор 2float со скоростью движения при движении и 1 триггер на выстрел, при выстреле.  Передавать по стрингу вообще моветон, что мешает сделать хэш при загрузке и юзать его? функции CalculateShootPoint и CalculateShootAngles можно заменить одной строчкой на каждую. Со столкновениями полная ересь, столько проверок за 1 кадр, что старенький комп уже не справится. Не проще использовать тэги и слои для столкновений и считать только 1 раз? Короче всего и не описать, но последнюю статью я бы назвал "оптимизация" и сделал работу над ошибками

раскрыть ветку (10)
2
Автор поста оценил этот комментарий

С тем, что всё можно было сделать лучше - не поспорю. Так уж сложилось, что ни одной игры за всю жизнь я до конца не дописал, ни одной игры не выпустил, и ни с кем вопросы написания кода не обсуждал. Один из поводов для записи этих серий как раз-таки и является решение проблемы обсуждения кода с людьми.

Всё, что записано на видео - полная импровизация, поэтому многое в коде может быть тем ещё велосипедованием и инкостыляцией. Но, на данном этапе код меня устраивает по двум критериям:

1. Он полностью мне понятен.

2. Он выполняет все задачи, которые я перед ним поставил.

Идея сделать рефакторинг в последних видео серии - отличная, я ей, пожалуй, воспользуюсь.

Спасибо за критику.

Автор поста оценил этот комментарий

// Передавать по стрингу вообще моветон, что мешает сделать хэш при загрузке и юзать его?
Ничто не моветон, если работает и цифры в profiler'e устраивают(для конкретной стадии разработки). Так то и по transfrom обращаться нельзя, если код вызывается часто(а так же, юзать делегаты, использовать list, брать .name() у обьектов и много чего еще), потому как все это сильно накручивает alloc. Но это ж охренеть можно, на стадии прототипа за всем этим следить :)

А вот логика, вызываемая в Update() ( и Start() ) это, согласен, то, чего следует избегать, по возможности. Иначе, потом будет заметно сложнее во всем этом разбираться, и вот это уже косяк архитектуры проекта.

раскрыть ветку (8)
Автор поста оценил этот комментарий
Так то и по transfrom обращаться нельзя

я может что-то не понял, можно подробнее? К чему тогда обращаться вместо трансформа?

раскрыть ветку (7)
Автор поста оценил этот комментарий

Я сам офигел, когда узнал. Там в самых диковинных местах может быть alloc... Когда у тебя много объектов (например, толпа людей на трибуне, которые следят за гонкой и вертят головами за машинками), то, в профайлере, таки, набегает. (каждый кадр берутся трансформы костей, чтобы подворачивать им головы до цели)
Я пришел к выводу, что если объекты статичны(или почти статичны), то имеет смысл "запечь" их позицию, чтобы потом брать из класса:
// ...
staticPos        = transform.position;

staticForward = transform.forward;

// ...

for (int i = 0; i < targetsDir.Count; i++) {

    targetsDir[i]  = dynamicObj - staticPos;

    targetsDot[i] = Vector3.Dot(staticForward , targetsDir[i]);

    // ...

}


Но вообще, обычно, на это можно и забить.
У меня такое было, когда оптимизировали под "бокс one" (там каждый ms на вес золота).
Может я, конечно, попутал что-то, но помню, как офигевал с самых удивительных вещей, который жрут дофига персоманса, в частности, это.

раскрыть ветку (6)
Автор поста оценил этот комментарий
"запечь" их позицию

если объекты статичны, то по-другому и делать нельзя, смысл обращаться к позиции через трансформ, если можно при старте эту позицию запомнить. Вопрос в другом, как эту позицию менять, не обращаясь к трансформу? Юнити те еще хитрые пиздюки. Нет исходников, нигде не сказано, как че работает, в том числе и get трансформа, но я думаю что-то типа GetComponent<Transform>() там внутри. Может имеет смысл при старте присваивать трансформ переменной? типа так


Transform trans;


void Start(){

    trans = transform;

}


void Update(){

    trans.pos+=value;

}


но это имеет смысл при работе с большими массивами

раскрыть ветку (5)
Автор поста оценил этот комментарий

// если объекты статичны, то по-другому и делать нельзя
Да. Ну как...можно, если логика не в апдейте и экземпляров класса не сфене немного - там вообще пофиг :)

// что-то типа GetComponent<Transform>() там внутри.
Если так, то остается только сказать: О - оптимизация.
// Может имеет смысл при старте присваивать трансформ переменной? типа так
Если у них там проперти, которая возвращает GetComponent<Transform>(), то да.
Но если transfrom там - переменная, то тогда смысла нет, т к по .transfrom мы просто получаем reference, что не должно давать тормозов.
// trans.pos+=value;
В этом случаи, trans = transform, будет бессмысленным, потому как trans это reference... а pos,все равно, берется как новый value type у оригинального transform.
Вот поэтому я, на всякий случай, оговариваюсь, что точно не уверен, но помню, что там были странности - в общем, если будешь оптимизировать штук 100-200 трансформов в сцене - обрати особое внимание.


//но это имеет смысл при работе с большими массивами
Это да. Все проблемы от количества.

раскрыть ветку (2)
Автор поста оценил этот комментарий
Если у них там проперти, которая возвращает GetComponent<Transform>(), то да.

я вот и говорю, что может там это, а может просто переменная. Но если она просто переменная, почему остальные так не сделали, а через GetComponent только? Причем раньше можно было обратиться к gameObject.rigidbody, а сейчас только через GetComponent. И нигде не написано как вообще этот GetComponent работает, может у них вообще тупо переменные создаются на старте приватные, где есть все компоненты и возвращают таким макаром их, чтобы публичными переменными не засирать. Никто не знает короче:) Причем кучу вопросов уже видел, типа что быстрее Invoke или корутины, быстрее вызывать Invoke 30 раз в секунду или Update 60 раз в секунду и т.д. Все это одна большая загадка

раскрыть ветку (1)
Автор поста оценил этот комментарий

//Но если она просто переменная, почему остальные так не сделали, а через GetComponent только?
Да, там больше вопросов, чем ответов...истина где-торядом.
//что быстрее Invoke или корутины
У меня с Invoke печальный опыт(баги), поэтому, обычно, юзаю корутины(хотя, это тоже опасная вещь, имхо)...
Но только в крайних случаях(например, если нужно сделать мультифрейм логику так, чтобы она занимала не более N времени в каждом кадре - pathfinding, скажем), потому как, часто можно вообще без них - через коллбэки или же стейт машина на аним контроллере.(лол, можно даже теймеры так сделать - анимконтроллер, анимация на 1 сек и изменяешь ей timescale под нужную задержку :D )

Автор поста оценил этот комментарий

//Вопрос в другом, как эту позицию менять, не обращаясь к трансформу?

Разве что, через Rigidbody.MovePosition(), в надежде, что оно cработает быстрее, хехе :D

раскрыть ветку (1)
Автор поста оценил этот комментарий
в надежде, что оно cработает быстрее

надежда, как говорится... там скорее всего пара проверок будет на столкновения, потом по тому же трансформу передвинет

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку