Comments 32
Не совсем понял, зачем поворачивать весь уровень?
Можно ведь на самом деле двигать игрока и камеру вместе с ним.
А про физику, Transform и производительность — спасибо, этот момент обычно как-то замалчивается.
Можно ведь на самом деле двигать игрока и камеру вместе с ним.
А про физику, Transform и производительность — спасибо, этот момент обычно как-то замалчивается.
В статье про это написано. Игра бесконечна и координаты объектов, в определенный момент, могут начать обрубаться из-за того, что хранятся в float, что приведет к ужасающим багам. Как вариант — можно периодически телепортировать игрока обратно в (0;0;0), но это, опять же, приводит к лагам, в статье про это тоже написано :)
Если я правильно понял, предлагается уровень только двигать, а игрока и камеру только вращать.
Да, можно, как вариант. Почему-то не додумался до такого, спасибо. Возможно, так будет даже производительнее, возможно — нет, уже не имею профайлера, чтобы сравнить.
Но не суть важно, как это сделано конкретно в нашей игре, она в статье использована лишь как пример соблюдения и осознанного несоблюдения основных законов. И полное вращение уровня — хорошая демонстрация гибкости физики в Unity на низком уровне.
Но не суть важно, как это сделано конкретно в нашей игре, она в статье использована лишь как пример соблюдения и осознанного несоблюдения основных законов. И полное вращение уровня — хорошая демонстрация гибкости физики в Unity на низком уровне.
UFO just landed and posted this here
С движением вперед и прыжком все правильно, а вот повороты нужно делать, временно отклоняя вектор скорости.
Для этих целей гораздо лучше подойдет CharachterController с его методом Move()
А как игра-то называется?
Хинты про производительность были особенны полезны.
Это как-раз тот опыт который экономит время.
Спасибо :)
Это как-раз тот опыт который экономит время.
Спасибо :)
Я верно понял, что все актёры сцены должны генерироваться «в чулане» (далеко от сцены) сразу при загрузке уровня и телепортироваться на нужное место уровня во время игры по мере надобности?
Я вот тоже делаю свой первый endless runner (не на Unity) и разбираюсь с такими же вопросами. Тоже изначально сделал движение уровня относительно игрока, но вижу, что производительности не хватает даже на моем Nexus 5. Теперь переделываю на движение игрока (и камеры вместе с ним) по генерируемым перед камерой участкам уровня. То есть, случайным образом, берется один из вариантов бэкграунда (которые бесшовно в друг друга переходят), на нем, опять же случайно, расставляются препятствия, а после прохождения игрока сегмент очищается и возвращается в пул для повторного использования. Думаю, размерность float значительно больше расстояния, которое игрок будет способен пройти даже для самой длинной игровой сессии. Ну а после рестарта уровня, телепортируемся в ноль-ноль, понятно.
Кинематические тела следуют упрощенным правилам симуляции — на них не воздействуют никакие внешние силы, гравитация — в том числе. Они свободно могут проходить через что угодно.
Кинематические тела не должны свободно проходить через что угодно. По крайней мере, все именно так в Box2D, который используется в Unity. Возможно, вы что-то напутали в настройках слоев?
Если использовать isKinematic то можно смело обращаться к transform и не будет необходимости работать через Rigidbody.
Если вы используете физические расчеты перемещения то применяйте силы в FixedUpdate, а не в Update.
Если вы используете физические расчеты перемещения то применяйте силы в FixedUpdate, а не в Update.
Надеюсь, Unity не сильно обидится на меня за еще один триал…
Можно, да, но с падением производительности, где-то в два раза. Таков третий закон. Точно такая же картина с не-кинематическими телами.
Тест на 20 box-коллайдеров (больше лень было создавать). Слева — движение через rigidbody2d.MovePosition, справа — движение через transform.position.
Можно, да, но с падением производительности, где-то в два раза. Таков третий закон. Точно такая же картина с не-кинематическими телами.
Тест на 20 box-коллайдеров (больше лень было создавать). Слева — движение через rigidbody2d.MovePosition, справа — движение через transform.position.
Использованный для теста код
void FixedUpdate() {
float v = Mathf.Sin( Time.timeSinceLevelLoad );
Vector3 newPosition = stockPos + new Vector3( v, v );
if( byTransform ) {
cachedTransform.position = newPosition;
} else {
cachedRigidbody.MovePosition( newPosition );
}
}
слишком сложно, для такой простой игры…
Все игры кажутся простыми, если ты их не делал :(
Ну и это все же обучающая статья, если разработчик переживет эти проблемы — дальше ему будет проще.
Ну и это все же обучающая статья, если разработчик переживет эти проблемы — дальше ему будет проще.
Я вполне адекватно представляю как ее сделать. Я не считаю себя мега крутым разработчиком, но кое что из своей жизни я понял. Чем проще, тем лучше. Я не спорю, всегда что то кажется проще, пока ты не делал, это наш оптимизм ;)
Но я имел введу, что я бы сделал совсем по другому, и многие вопросы для меня просто не появились бы во время разработки :)
Тем не менее! Я рад что Вы поделились своим опытом с хабра-сообществом, я вот почему то не осилил и даже не думаю что это будет кому то интересно.
Но я имел введу, что я бы сделал совсем по другому, и многие вопросы для меня просто не появились бы во время разработки :)
Тем не менее! Я рад что Вы поделились своим опытом с хабра-сообществом, я вот почему то не осилил и даже не думаю что это будет кому то интересно.
Само собой. Просто если не знать особенностей инструментария — иногда простые решения могут не работать, или работать неожиданно медленно :)
Как бы вы сделали, если не секрет? С учетом обхода очевидных проблем, описанных в статье, конечно же.
Как бы вы сделали, если не секрет? С учетом обхода очевидных проблем, описанных в статье, конечно же.
Для начала, я бы не использовал юнити, это лишнее обременение. Cocos2d-x тут бы хватило за глаза. Группировал рендер в батчи и двигал бы мир(он генерируемый, а значит ему существовать целиком не обязательно), вернее пулы кусочков мира. Использовал бы Box2D или нет, сложный вопрос, скорее нет, чем да. Мобильные платформы обременяют на размерность текстур и как мы помним переключение текстур до сих пор тяжелая операция. Поэтому максимум атласов текстурных. Могу с уверенностью сказать что даже самый галимый девайс на андройде весело срендерит батчинг на одной текстуру 1024х1024 нежели несколько 64х64, постоянно переключаясь.
Если вам интересно то можете найти в эпсторе (плей маркет) игру Выкрутасы. Хоть я там давно и не работаю, а мое имя в создателях потерли после обновления графики(да и кода наверно), я свой код все равно узнаю. Так вот, из за технических ограничений мне пришлось прокидывать видео с камеры через память озу. Это довольно дорогая операция, но я постарался максимально оптимизировать. Эта игра может показаться проще вашей, но как вы говорите «если ты их не делал» ;) хотя ничего сложного, там действительно нет. Больше грабли и сложности связанные с не нативной разработкой и желанием записывать видео игры. (особенно интересно было объединение видео и текста, у меня осталось время даже для этого)
Если вам интересно то можете найти в эпсторе (плей маркет) игру Выкрутасы. Хоть я там давно и не работаю, а мое имя в создателях потерли после обновления графики(да и кода наверно), я свой код все равно узнаю. Так вот, из за технических ограничений мне пришлось прокидывать видео с камеры через память озу. Это довольно дорогая операция, но я постарался максимально оптимизировать. Эта игра может показаться проще вашей, но как вы говорите «если ты их не делал» ;) хотя ничего сложного, там действительно нет. Больше грабли и сложности связанные с не нативной разработкой и желанием записывать видео игры. (особенно интересно было объединение видео и текста, у меня осталось время даже для этого)
А можно вопросик по поводу gameObject.SetActive? Имеется пул. Что будет лучше(и быстрее), перемещать объект в Infinity координаты и отключать только пользовательские компоненты или делать gameObject.SetActive? Объект имеет сложную иерархию.
Недавно товарищ столкнулся с тем, что имея на объекте Animator при SetActive терял очень много времени именно на нем. Хотя в том же официальном примере object-pool-а используется SetActive.
Недавно товарищ столкнулся с тем, что имея на объекте Animator при SetActive терял очень много времени именно на нем. Хотя в том же официальном примере object-pool-а используется SetActive.
Мы используем SetActive и проблем с ним не было. Иерархия блоков и врагов тоже сложная бывает, скриптов куча, отключать каждый компонент — не вариант.
Аниматоры еще весьма прожорливы в режиме ожидания (значит, лучше их все же отключать) и действительно долго инициализируются. Но я с ними плотно не работал и не могу с уверенностью дать совет. Возможно, стоит их создавать активными, давать им возможность проинициализироваться, а потом выключать?
У нас в игре аниматор только один на весь UI, все мелкие движения на скриптах.
Аниматоры еще весьма прожорливы в режиме ожидания (значит, лучше их все же отключать) и действительно долго инициализируются. Но я с ними плотно не работал и не могу с уверенностью дать совет. Возможно, стоит их создавать активными, давать им возможность проинициализироваться, а потом выключать?
У нас в игре аниматор только один на весь UI, все мелкие движения на скриптах.
В документации написано, что если на обьекте есть коллайдер и его нужно двигать, то на нем обязан быть RigidBody — иначе будет серьезное падение в производительности.
Скорее всего это у вас и было — проверьте профайлером коллайдеры еще раз, но сначала на обьект повесьте RigidBody (Иначе получается глупо — зачем нужны коллайдеры, если обьекты нельзя двигать?)
Скорее всего это у вас и было — проверьте профайлером коллайдеры еще раз, но сначала на обьект повесьте RigidBody (Иначе получается глупо — зачем нужны коллайдеры, если обьекты нельзя двигать?)
Sign up to leave a comment.
Борьба с 2D-физикой в Unity на примере бесконечной игры