Приветствую вас, дорогие форумчане. Во время работы в Unity у меня возник один довольно коварный вопрос, ответ на который я так и не смог найти в великом Google. Точнее я нашел заметку на официальном сайте на форуме, но не понял метода реализации... Суть вопроса: мне необходимо, чтобы при движении персонажа модель поворачивалась по осям x и z так, что персонаж постоянно ногами находился на земле. Идеальный пример реализации - серия игр про Sonic'а от Sega. Есть так же видео, где данная вещь показана на Unity: http://www.youtube.com/watch?v=LGbWo9Da40M.
Мне известно лишь то, что это можно реализовать, проводя нормаль в точке столкновения с сурфейсом поверхности и поворотом на *какой-то вектор(вроде направление движения или transform.up)* -> сама нормаль (RaycastHit.normal или collision.contacts[number].normal).
Код
var moveDirection = Vector3(Input.GetAxis("Horizontal"),0.0,Input.GetAxis("Vertical")); moveDirection = transform.TransformDirection(moveDirection); PlayerController.Move(moveDirection*walkSpeed*Time.deltaTime);
P.S>Оно мне не особо нравится, ибо создается эффект скольжения при повороте персонажа. Использую его так, как через transform.forward при движении по склону, персонаж дергается и скорость спуска уменьшается. Как только появится поворот модели, этот феномен исчезнет. Если не сложно, то может быть вы знаете другой способ перемещения? =)
Персонаж представляет из себя префаб, на котором висит Character Controller и сам скрипт управления. В дочерних объектах находится Camera и префаб модели персонажа со скелетом и мешом. На нем так же висит компонент Animation. В качестве поверхности используется обыкновенный Terrain.
Думаю, что этой информации вполне достаточно для описания моей ситуации. Спасибо за внимание и надеюсь на вашу помощь
P.S>Если будет необходима дополнительная информация о персонаже - сообщите, я предоставлю.
Как в Unity3d отключить Backface Culling(т.е. включить отрисовку обратной стороны полигона. При экспорте из 3D's Max она отключена)? вроде через шейдеры можно, но не совсем понятно как. Спасибо.
Мне известно лишь то, что это можно реализовать, проводя нормаль в точке столкновения с сурфейсом поверхности и поворотом на *какой-то вектор(вроде направление движения или transform.up)* -> сама нормаль (RaycastHit.normal или collision.contacts[number].normal).
Не все так просто, если копировать normal.up на transform.up остальные оси это тоже затронет. Надо или ровнять родителя а поворачивать парента и двигать уже по его форварду. Или загонять normal.up в временную переменную и брать оттуда нужные оси на transform.eulerAngles. X.cor.R (Prologue)
Но вот теперь появилась загвоздка - Terrain слегка шершавый и из-за это персонаж при движении слегка вибрирует(дрыгается, чувствуя каждую кочку). Либо мне выравнивать Terrain, либо как-то смегчать поворот... Может подскажите?) Благодарю за внимание
Добавлено (14.07.2014, 06:15) --------------------------------------------- Неее, способ себя не оправдывает - прыжки камеры и модели просто дикие, поворот не всегда работает... Надо контроллер на модель вешать вероятно..
Левша, Большое спасибо, интерполяция прекрасная вещь =) С горем пополам и бомбежкой Google я научился поворачивать объект вокруг локальной оси и теперь все выглядит просто Щикарно. Вот код, чтобы с такой проблемой никто не сталкивался:
P.S>Ответа на маленький вопрос про Backface Culling никто не знает?
Добавлено (14.07.2014, 10:00) --------------------------------------------- Эх... способ работает, но сглаживание достичь все равно не удалось. Бывают моменты, что модель дергается даже на ровной поверхности. Но как же в видео все так удачно реализовано..
Левша, Да нет. Камера по осям x и z вообще не поворачивается (пока, позже попробую сделать плавный поворот камеры за объектом). Тут дело в том, что нормаль поверхности получается каждый фрейм, и порой на вроде бы ровной поверхности она получается отличной от предыдущей. И, как следствие, объект резко поворачивается в ненужную сторону, а потом возвращается в исходное положение. Отсюда и появляется "дрожание" и "вибрация". Думал выровнять terrain в Photoshop, но не помогло. Все равно почему-то имеется такой феномен. Ninja Slayer - 2D Physics Puzzle [cancelled]
Сообщение отредактировал Abel399 - Вторник, 15 Июля 2014, 08:14
allods, Да, в паренте. Но это не имеет значения ибо дрожит не камера, а сам персонаж, который наклоняется к поверхности. И камера следом за ним. Камеру можно и скриптом плавно поворачивать. Левша, Я вас понял. Дело в том, что я плохо объясняю =) смотрите: Вот поверхность:
Вот на этом бугре или неровности поверхности, персонаж поворачивается перпендикулярно бугру. Потом опять встает на сглаженную поверхность и нормально поворачивается. Вы предлагали поворачивать объект на угол в градусах по нужным осям. Это правильно, да. Но ведь можно поворачивать и сразу по компонентам Quaternion для меньших расчетов (здесь, возможно, вы можете не понять мою мысль из-за моих ужасных объяснений :D). Если идеально выровнять поверхность terrain, сделать небольшую сопочку (обязательно ровную и без сглаживания, чтобы не было бугорков), то наклон будет идеальным и правильным, без "тряски". Т.е. нужно как-то сделать так, чтобы если поверхность резко меняется в течении какого-то времени, то скрипт игнорировал поворот или же запрещал очень резкие повороты.
Эх.. Надеюсь моя писанина хоть немного понятна. Спасибо за уделенное внимание
P.S>А вообще это происходит из-за постоянной смены нормали к поверхности. Их видимо много в одном месте и =>Смена наклона очень резка и быстра. Ninja Slayer - 2D Physics Puzzle [cancelled]
Сообщение отредактировал Abel399 - Четверг, 17 Июля 2014, 09:49
Abel399, Делаю игру про соника(уже во второй раз) и тоже сталкивался с такой проблемой!Если я правильно понял вопрос,то чтобы он не дергался можно скорость поворота снизить.Я же в своем проекте нашел такой косяк-если я перпендикулярно поверхности поворачивал character controller то была тряска дикая - соник был то перпендикулярно то по оси у направлен,тогда я стал поворачивать перпендикулярно поверхности дочерний к character controller'у пустой объект и тряски не было.Так что я просто модель персонажа засунул внутрь этого объекта.Он только ставит персонажа перпендикулярно поверхности.А двигается он(персонаж) в ту сторону,в которую смотрит модель игрока.
Сообщение отредактировал Fr0sT - Суббота, 19 Июля 2014, 00:12
Fr0sT, Спасибо за отзыв :-) Я так и делаю. У меня character controller висит на общем префабе, а внутри него сама моделька персонажа, которая и поворачивается. А у тебя все-таки получилось смягчить поворот? Левша, В связи с моим неполным пониманием функции, я отложил это дело до ближайшего времени. Сейчас занимаюсь основной игровой логикой, но над решением данной "мелочи" все ещё думаю :-)
Fr0sT, Ясно, появилась мыслЯ. У меня просто поворот меняется каждый кадр => сглаживание тут не ощущается. И есть два выхода: сохранение времени или установка контрольных точек поворота через равные промежутки времени, что наверняка напоминало твою реализацию. Буду пробовать Ninja Slayer - 2D Physics Puzzle [cancelled]
Abel399, как вариант - рейкастом по тегу или по лэйеру брать нормаль с параллельного террейну объекта, который просто не рендерить. Т. е. террейн останется со своими буграми и впадинами, но персонаж всегда будет повернут перпендикулярно плоскости террейна. А вот ноги персонажа или только стопы ног, при If Grounded = True, параллелить уже по форме (нормали) террейна (буграм и впадинам), определяемой отдельным рэйкастом по самому террейну.
Сообщение отредактировал CyXoB - Суббота, 30 Августа 2014, 10:14
Вот я похожую штуку делал: http://youtu.be/YQYywmPtrl8?list=UUgn9Mowbhb4btLD7GsSR1xQ Рейкастил не лучем, а сферами. Чтоб не дрожал перс, - не надо ему постоянно угол менять, а только когда он в движении (прыгает/падает, бежит). И камера у меня там отдельно летает и сглаживается сама по себе, независимо, ни к кому не удочерена, просто в таргет добавлен персонаж, если кому интересно, вот скрипт:
Код
using UnityEngine; using System.Collections;
public class MagicCamera : MonoBehaviour {
public Transform targetCharacter;
public float posDamp; //2 public float rotDamp; //3 public float height; //2 public float distance; //5