Всем привет! В этом посте покажу вам как сделать то, что на гифке выше с помощью Blueprints.
В Unreal Engine 4 есть очень классная вещь - Construction Script. Его фишка в том, что он выполняется прямо в редакторе, когда вы размещаете или редактируете ваш объект. Попасть в него можно на том же уровне вкладок, где находится Event Graph, либо в разделе функций вашего блупринта.
Далее рассмотрим Construction Script на примере моей палатки. Он включает две моих функции: Place All Sticks размещает все колышки, а TurnAllRopes поворачивает и скейлит все веревочки.
Чтобы это хорошо работало, я имею (StaticMesh) веревочку длинною 100 юнитов (1 метр) с правильным пивотом. В данном случае, он находится на краю, а сама веревка направлена по локальной оси Х этого меша. Это нужно для того, чтобы дальше было легко поворачивать и скейлить этот объект.
Веревку я привязываю к колышку. Ну, то есть, размещаю "внутри". Таким образом, её координаты будут локальными относительно колышка. А вот вращение для веревки выставляю абсолютным.
У самой палатки я подготовил 8 сокетов, к которым буду "привязывать" веревку.
Теперь вернемся к нашим функциям PlaceAllSticks и TurnAllRopes. На самом деле, в каждой из этих функций просто вызывается 8 раз своя дополнительная функция для единичного случая. То есть, вот на примере с веревками. С колышками то же самое.
Как это работает для единичного случая?
Сначала нам надо воткнуть колышек по уровню лэндскейпа. Тут в дело вступает функция PlaceStick. Она берет на вход колышек, пускает луч по каналу Landscape (это мой собственный канал для ландшафта, но вы можете использовать дефолтный Visibility, если хотите) из точки [локация колышка + 500 по Z] в точку [локация колышка - 500 по Z]. Далее, если произошло столкновение, мы меняем координату Z колышка на точку столкновения.
Я еще добавляю небольшой рандом (поэтому на гифке выше колышки немного трясутся). Понятное дело, вы тут должны учесть пивот вашего колышка. В моём случае он по центру и я могу размещать колышек прямо в точке столкновения луча с ландшафтом. Если бы пивот был на кончике, я бы просто добавил вектор смещения в эту функцию.
После того, как мы разместили колышек по ландшафту, в дело вступает функция TurnRope. На вход она принимает саму веревку, а также сокет на палатке, в которому мы будем "привязывать" веревку. Тут, конечно, придется засинхронить всё вручную (подобрать к каждой веревке свой сокет).
Напомню, у нас есть веревка, которая расположена в самом колышке. Теперь нам надо её повернуть и изменить длину.
Для поворота есть отличная стандартная функция в Unreal Engine 4 - FindLookAtRotation. Она принимает точку старта (локация нашего объекта) и точку, на которую он должен повернуться (Target). Соответственно, выдает нам Rotation, который мы просто назначаем нашему объекту. Не забываем про то, что в Unreal Engine 4 Forward Vector любого объекта направлен по его локальной оси Х.
(Учтите, в моём примере я всё вычисляю в мировых координатах, потому что мне так удобней!)
После поворота, нам остается только поменять длину этой веревочки. Вычисляем расстояние между началом и предполагаемым концом веревочки, делим это расстояние на 100 и забиваем в скейл по Х для нашей веревочки. Вуаля.
(На 100 мы делим потому, что наша веревка изначально длиной в 100 юнитов)
Теперь я могу двигать палатку по ландшафту, а её колышки всегда будут подгоняться под окружающий рельеф. Это намного проще, чем выставлять такие вещи вручную для каждой палатки :)
Буду рад, если мой опус кому-нибудь поможет. Спасибо за внимание!