Как убрать эффект разделения стола на части в изометрии?
Допустим у меня стойка бармена, и мне не нужно получить эффект, как на 2-й картинке,
а нужно сделать как на третьей, чтобы стол выглядел целостным, хоть он и состоит из отдельных тайлов. Как достичь такого результата в Godot, GMS или Unity?
PS Справа пример из Light Crusader на мегадрайве, где удар от меча нормально обрезается.
- 29 марта 2021, 09:48
- 00
Наверное стоит получать Z не только по X,Y, но и ещё по уровню. Если блок трехмерный - то надо ещё + 1 делать.
Спасибо! Попробую потестировать)
Возможно я не так понял, но не получается.
Если задействовать ещё координату высоты, то исправляется проблема сверху стола, а снизу появляются другие косяки, когда в Light Crusader даже так всё хорошо и меч не проходит сквозь тайлы.
Однако понял, что во многих играх встречаются подобные косяки, и мне кажется что при таких формах столов используют хитрости, возможно переключения номера сортировки самого стола или что-то подобное.
1) хотя в Light Crusader нашёл момент, где рассыпается иллюзия трёхмерности (меч проходит сквозь пол):
2) Ещё в Boktai 2 на GBA при ударе мечом видны косяки с тайлами. Там где косяков нет,
тайлы просто находятся на другом слое, выше или ниже слоя с героем.
3) Тоже самое и в Kingdom Hearts на GBA, там большая часть тайлов просто на заднем плане, а лишь редкие тайлы находятся на слое с героем, и даже они стараются быть квадратной формы, а не прямоугольной, мне кажется если добавить сюда прямоугольную форму, то иллюзия распадётся и ключ пройдёт сквозь тайлы,
чтобы этого не происходило, видимо делают разные хитрости с переключением слоёв или просто сортировки.
А ещё можно хитрить с коллизией и делать запрет на попадание на ту территорию, где иллюзия рассыпается,
например запретить попадать за стойку бара.
PS В конечном итоге, я просто хотел сделать стойку бара в таверне и понял, что оказывается это очень сложно без косяков.
PPS хотя может я не совсем понял про Y координату
PS Мне предложили интересный вариант - сделать проверку сортировки отдельно для оружия в зависимости от его координат, надо потестить.
Судя по другим играм - разработчики просто не заморачиваются с такой ерундой, а делают игру ;) Ты вместо того, чтобы делать игру тратишь время на ерунду. В итоге кто-то игры делает, а кто-то ... ну ты понял. Не надо заниматься ерундой короче ))) Времени и так мало. Юзеры будут в игру играть, а не тайлы разглядывать как сквозь них меч проходит. Сам подумай. Будет лучше хорошая игра, но с мелкими малозаметными косяками, или хорошо проработанная, но которую ты никогда не закончишь ))))
"А мог бы игры делать!" )
Только этим и занимаюсь. Ну просто выводи блоки поверх всего остального. И не надо будет ничего придумывать. Но это когда персонаж (за ними), а когда (перед ними) - его выводи поверх. А если идут такие визуальные косяки просто оставь как есть. Если что-то не получается можно оставить на время, а спустя время может будет у тебя больше опыта - и тогда исправишь. Или так и останется ))))
Кажется нашёл решение:
Синий многоугольник - это коллайдер/триггер, с которым при столкновении все объекты с сортировкой будут увеличивать свою сортировку например на 10-100 пунктов, ещё не тестировал, но кажется должно получиться.
Но это будет работать только для статических локаций и вручную проставленных как объектов, так и подобных "синих" коллайдеров.
PS Только это не подойдёт для игр в духе Sims, где можно самому мебель расставлять по дому, скорее всего в Симсах объект состоит из нескольких составных частей, и из-за того что персонаж не широкий, и не может бить, то из-за этого не видно что диван состоит из как минимум 2-х кусков.
PPS Хотя есть одно решение для Sims-оподобных игр, динамическую мебель делать не в изометрии, а с прямоугольной перспективой, где все диваны и кровати будут под ровным углом, всё равно планирую сделать движок, который может сразу работать как с изометрией, так и с обычными прямоугольными объектами,
своего рода Freeform.
PS А в GMS, можно вместо полигонного коллайдера использовать просто отдельный невидимый слой тайлов или любых других способов столкновения, при столкновении с которым у героя будет повышаться сортировка сразу на несколько пунктов.
Как раз тут недавно запилил в GMS псевдоизометрическую коллизию которая может и в изометрическое столкновение и в прямоугольное. То есть просто 5 тайлов, прямоугольный и 4 "скоса" в разные стороны, эти 4 "скоса" при сборке могут дать аналог изометрической коллизии:
GIF:
PS Туплю, всё намного проще в GMS, достаточно просто квадратную тайловую сетку для проверки увеличения сортировки, главное чтобы эти прямые тайлы с расположением изометрических предметов совпадали.
Даже не надо треугольных тайлов.
Как вариант, что мне пришло в голову: после сортировки по z, выбирать ближайший к игроку блок и отправлять к нему по z соседние с ним
Возможно я не правильно представил, но если часть объектов на экране изменить по Z, то другая часть не ближайших к игроку блоков, но видимых на экране могут конфликтовать с теми объектами которые были скорректированы. Ну если я правильно понял.
Да, наверно, не годиться, надо двигать игрока.
Ты ошибся занятием, Алекс, делай то что у тебя хорошо получается - игру!
Он хочет разобраться с проблемой, не для того чтобы сделать (или не сделать) игру, а чтобы окончательно убедиться - сможет ли он вообще её сделать. Тут проблема упирается в решение задачи, пока не решишь - не двинешься дальше. Кто-то просто пропускает такие моменты, закрывает на них глаза, делает другим способом или вообще делает такие игры, где таких проблем не возникает. Лет 10 назад (а может уже и больше), я тоже только учился программировать и делал примерно также. Может поэтому и сделал свой движок. Думаю он не ошибся занятием. Но мы лишь можем посоветовать да. Но никоим образом не указывать.
Конечно не сможет. Чтоб вообще сделать игру надо её вообще делать, а тут пока годами только "в Битси так, а в Юнити не так". И сегодня мусолится очередная проблема из разряда геометрии, но как выяснилось это чтобы сделать движок. А движки делать надо только если ты программист. И как правило это значит что ты игры не делаешь. Ну или одну сделаешь, как Кармак или там ещё какой Ромеро.
В случае с "удобными скриптами" всё ещё наполовину верно. Но идеально было бы, если бы делалось всё под ПЕРВУЮ игру, а не под N игр которые будут неизвестно когда.
Ксит, ну то есть сборку из скриптов, из которых можно собирать быстро игры.
Как это легко получается в том же Битси.
С одной стороны согласен - так это звучит лучше. С другой не согласен - даже так это звучит сомнительно. Ты сначала одну игру быстро сделай, не надо закладывать изометрия+топдаун+2.5Д в желаемые фичи. Речь-то идёт о том чтоб стартануть хоть с каким-то релизом, а ты обустраиваешь всё так основательно, как будто у тебя целый цех по производству игр. XD
Жаль нет варианта UE4, а то я бы подсказал... нет.
Третий вариант так-то тоже неправильным выглядит. Вероятно, надо спрайт удара отдельным от персонажа делать.
я бы скорее сделал отдельную проверку столкновения + высоты, и в зависимости от высоты объекта заканчивал анимацию.
Интересный вариант, если сделать прерывание анимации при ударе по предмету как в Mount & Blade, то часть проблемы возможно даже решиться.
Можно сделать так чтобы оружие всегда было выше тайлов, кроме тех стен, которые явно впереди всех.
Но иногда при анимации можно будет видеть другую проблему: то что рука находится за столом, а оружие выше стола, хотя в какой-то мере это будет не так плохо, как проблема с распиленным столом.
У тебя в примерах из Light Crusader тайлы за которые принципиально нельзя зайти никак - скоре всего глубина в них прописана как "всегда на переднем плане" и "всегда на заднем плане".
Прежде всего на этом скриншоте рассыпается иллюзия что у тебя меч - мечом так не машут, просто вводить это как дополнительную анимацию "попытался взмахнуть и не смог" - отдельная морока. Если там не заморачивались, то чего ты должен?
Во многих играх так и делают: "Всегда на заднем/переднем плане",
насколько понял в этой игре Light Crusader эта группа объектов наверное ещё и переключается по скрипту,
потому-что можно встать по другую сторону стола и кажется будто он со всех сторон идеален, в принципе
видимо так и придётся менять сортировку некоторых прямоугольных объектов в зависимости от того где находится герой или наоборот у героя менять сортировку если он попадает в особую координату.
В Unity можно объединить тайлы стола в одну группу с помощью компоненты SortingGroup. Тогда стол будет рендерится как одно целое.
А что это даст? На какой глубине будет стол с первого скриншота - на средней?
Я могу даже вообще забить на тайлы и делать прямоугольные объекты сразу, это как аналог группы тайлов, и юнити, и GMS позволяет, но проблема в том что середина объекта определяет тогда когда герой должен быть рисоваться за объектом, а у прямоугольного объекта как минимум 2 середины будет, поэтому тут никак не сделать :( придётся распиливать на части, или делать другие хитрости.
PS Красная линия это, то когда другие объекты должны рисоваться за пределами этого объекта.
Я вот еще такую идею нашел -
сортировка объектов
т. е. надо определить OrderBox — он будет определять прямоугольное основание объектов, согласно его размерам и расположению в пространстве будет вычисляться его сортировочный индекс для объекта. Звучит немного сложно, но на деле все просто.
Уже давно читал эту статью вот и вспомнил. У себя в проектах пока не применял, но возможно тоже попробую т. к. идея хорошая. Делать можно на любом движке, главное понять смысл идеи - это использование OrderBox`а.
Спасибо! Давно на сайте Антона Карлова не был
Я в своих проектах - Веселый Буквоежка и ria pc game (в аркадных сценах) использовал тоже вычисление z по отношению к y. Но всегда ломал голову над тем, как сделать чтобы визуально сортировка была правильной. То есть чтобы не было такого, что допустим персонаж стоит "за деревом", а его ноги висят снизу.
Оказывается решение простое. Тут даже не надо использовать OrderBox, достаточно будет top и height. То есть верхней точки и высоты. Формулы те же самые, что у Карлова, но конечно нужно адаптировать под реалии своего проекта.
И тогда вуаля - будет все корректно выводиться. Главное подобрать правильные параметры top и height. Надеюсь ты понял о чем речь ;)
Я вот прям сейчас тоже делаю сортировку (в проекте gdess2) там нужно деревья и кусты сортировать по z. И когда доделаю, попробую и вариант с использованием OrderBox - а именно top и height из него.
Горизонтальные параметры OrderBox, т. е. OrderBox.left и OrderBox.right нужны будут в том случае, если будешь сортировать еще и с учетом горизонтальных (x) координат.
Ну а в целом в статье у Карлова все достаточно понятно описано. Так что в любом проекте на любом движке думаю можно такое (при необходимости) реализовать.
Кстати посмотрел как у меня было в буквоежке сделано.
Там вот такой код (на c++)
То есть я по сути почти делал также как описано у Карлова. Только вместо OrderBox.top у меня тут vBottom - нижняя граница, и есть Height - но это не высота спрайта, а произвольная высота, т. е. как раз то же что OrderBox.height. Так что получается я уже это давно реализовал еще в буквоежке (в 2009 - 2010 году ))) ), и это по сути то что нужно. Ну а сами значения конечно надо подбирать опытным путем. Так что вот такой пример у меня из личного опыта ;) Роль нижней границы выполняет y -
vBottom = y; //для зеркальных спрайтов, а для обычных это просто y. То есть top я не использовал. Но его можно добавить например так -
Хотя насчет (y+Top) я конечно не уверен, что именно так. Надо проверять экспериментальным путем куда правильнее будет подставить Top. Но вероятно (теоретически) так правильно.
И таким образом:
CalcFleHeroZ(float y, float YScale, int Height, float Top)
y - координата спрайта, YScale - его масштабный коэффициент по оси y (если ты их не используешь, то можно опустить, а в формулах подставлять как 1.0f, Height - высота того самого OrderBox - т. е. OrderBox.height,
ну а Top - это как раз OrderBox. top и будет.
Не знаю как правильно это будет реализовано в твоих реалиях (на gml в game maker или c# в unity 3d), но думаю сообразишь. Тут никакого сложного кода по сути нет. Только арифметические вычисления.
Ну а сама формула -
float z = 0.80000001f - 0.00003071f +
(vBottom + 1.0f) / 2.0f / 10000.0f;
Как ты наверное понял - подобрана экспериментальным путем. И значения могут быть совершенно другие - исходя (опять же) из реалий твоего проекта. Т. к. я не знаю в каком диапазоне у тебя меняется y и в каком должно меняться z.
И например у меня в проекте для z есть 2 набора значений - одни для показа на экране, а другие для выполнения сортировки. Для сортировки они преобразуются в тип int, иначе сортировка не работает.
В принципе, я уже решил задачу
через быстрый костыль, где при столкновение с особой территорией
всем персонажам искажается сортировка на -2 пункта, а тот "барменский стол", который нужно обойти,
искажается на -1 пункт в самом скрипте сортировки вручную,
получается что мы не можем столкнуться со "столами" никак ни сверху, ни снизу:
https://gamin.me/posts/21436?comment=283051#comment_283051
Специально дал в руки 2 бревна :yak:, чтобы потестить насколько далеко можно бить,
чтобы не видно было искажение у "столов".
Но всё равно, Спасибо!
А формула сортировки выглядит попроще немного:
order = 3000-Mathf.RoundToInt((transform.position.y-high)*100);
где "high" - это искажение про которое в прошлом комменте упомянул,
по умолчанию оно равно нулю, но если делать меньше или больше, то объект насильно становится либо впереди многих объектов, либо позади многих объектов.
Да. Отлично. Главное, что получилось. Мне в этой формуле конечно не все понятно.
order это такое свойство у объектов в game maker ? То есть по сути z ? Или это тобой написанное что-то ?
3000 - это понятно какое-то экспериментально подобранное число.
Mathf.RoundToInt - округление до целого ?
transform.position.y - это y координата объекта и это как я понял тип float (ну то есть не целое, да ?)
high у тебя тоже имеет тип float ?
Ну а 100 - это опять какой-то экспериментальный коэффициент.
Кстати это на gml или на c# для unity 3d ? Или вообще что-то другое ???
В данном случае это в юнити порядок сортировки и C#. Sorting Order кажется называется,
Всё обновление сортировки у меня выглядит как-то так:
а в GMS тоже свой аналог есть сортировки, думаю там формула лишь слегка изменится.
на все вопросы: Да!)
PS А если кому интересно, то на Unity C# у меня весь скрипт сортировки выглядит так,
я надеюсь, и вроде тут нет системных переменных, которые беру из других скриптов, которых тут нет
и может выдаст ошибку, надо бы потом потестировать этот скрипт отдельно от всего:
Ну в 3d тоже полно косяков бывает. Стоит только начать делать игру. Да и у Алекса не совсем 2d игра, а изометрия, а с ней как известно проблем всегда хватает. Если бы он делал настояющую плоскую игру типа платформера с видом сбоку, тогда может быть проблем было бы и меньше. Но чем проще игра, тем с большей вероятностью в неё будет менее интересно играть, я уж не говорю, о том что делать. Когда делаешь игру на продажу или скажем на заказ - там да - думаешь не о том, как сделать все круче, а о том - как бы сделать проще, быстрее и получить денежку. А тут у нас другой случай. КАЧЕСТВО. И оно как известно не имеет ПРЕДЕЛОВ. ))))