rope swing荡绳
比我想的要复杂,目前还没查到简单的做法。本文为查资料的记录,积累后再做一个自己满意的荡绳蓝图。
一、某国外网友的解释
原文
https://forums.unrealengine.com/t/implementing-rope-swing/83098/15
Project Flake - Physics Rope Demo(视频地址油管)
Very late to the party, but I’ve been banging my head to create a rope behavior similar to what OP described for months, and I finally got it to where I’m quite pleased with the result. It’s for a 2D game, but the concept should work just fine for 3D as well.
You can see the prototype in action HERE 49
I made several prototypes with cables, physics constraints, spline mesh that all fell apart at one point or another before arriving at my current solution.
I’d be happy to break it down in detail if anyone is still looking for a way to create this kind of rope, but here’s my high-level approach:
-
The rope actor uses a skeletal mesh with a physics Asset as a base.
Compared to manually creating a rope with constraints and capsules, I found a bone-chain much more stable and easier to set up.-
Skeletal mesh can be swapped out per instance
-
Skeletal mesh set to invisible and hidden in game
-
-
Construction script adds a spline with points at each bone socket
Since the skeletal mesh still moved in Y even after all the axis were locked, I matched the spline to only X and Z to keep it on my 2D plane-
Spline used to add spline mesh
-
Spline mesh deforms much nicer than a skinned mesh and keeps its “thickness” well, especially when the rope coils in on itself
-
-
On Tick: Update spline points to match bone sockets, and update spline mesh to match spline points.
-
Skeletal mesh capsules use custom object channel “Rope Actor” with NO overlap events
-
Overlap events trigger the character movement impulse sent to physics bodies which I can’t control.
Since I’m doing 2D, I don’t want the rope to block my character, but still react a little bit when the character walks past. -
On Tick: trace for object type “Rope Actor”
-
Walking: Apply impulse to closest bone on rope based on values set per rope instance
-
Falling: Grab Rope (unless already on another rope)
-
-
-
Grabbing:
-
Get closest point on rope spline based on character trajectory, get distance along spline as target
-
Set movement mode flying and ignore rope collision
-
Timer Function: match character location to location of “Location at distance alone Spline” determined earlier
- Rotation of character is determined by a custom vector between current character location and a point “hand-distance”-away further up the spline
-
-
Climbing up/down:
-
On Up-Input, I run a timeline that outputs a distance float value and on update, add/subtract that value from my distance along spline variable
-
Location-match timer function keeps matching character location/rotation to the spline at that updated distance
-
-
Swinging:
-
Get a custom forward vector based on closest bone to character and root bone pivot for a nice arc, regardless of actual bone/character rotation
-
Calculate swing force
- There’s a lot going on here, but basically I wanted a short ease-in to full force and decrease the force as the character swings upward so I can’t just infinitely hover at an angle if I keep pressing in that direction
-
Rope applies force to bone closest to character AND fractional force to each bone above the target point, decreasing in strength the further away from the character the bone is. This is what really made the swing work for me - before that, the rope would always start to curve as I swung higher, and eventually become quite jerky and unstable
-
Obviously, lots of smaller things going on here and there, but that’s beyond the scope of a simple reply.
中文
主要部分中文翻译:
-
绳索演员使用以物理资源为基础的骨架网格。
*与手动创建带有约束和胶囊的绳索相比,我发现骨链更稳定,更容易设置。-
骨架网格可以按实例换出
-
骨架网格设置为不可见并在游戏中隐藏
-
-
构造脚本在每个骨窝处添加一个带有点的样条曲线
由于即使所有轴都被锁定,骨架网格仍然在 Y 中移动,因此我将样条曲线仅匹配到 X 和 Z,以使其保持在我的 2D 平面上 -
用于添加样条网格的样条
- 花键网比蒙皮网格变形得更好,并且可以很好地保持其“厚度”,尤其是当绳索自行缠绕时
-
在滴答时:更新样条点以匹配骨窝,并更新样条网格以匹配样条点。
-
骨架网格胶囊使用自定义对象通道“Rope Actor”,没有重叠事件
-
重叠事件会触发发送到物理物体的角色移动冲动,这是我无法控制的。
*因为我在做2D,我不想让绳子挡住我的角色,但当角色走过时,我仍然会做出一点反应。 -
在滴答声中:对象类型“Rope Actor”的跟踪
-
行走:根据每个绳索实例设置的值,对绳索上最近的骨头施加冲动
-
坠落:抓住绳索(除非已经在另一根绳索上)
-
-
-
抓住:
-
根据角色轨迹获取绳索样条上的最近点,获取沿样条线的距离作为目标
-
设置飞行运动模式,忽略绳索碰撞
-
定时器功能:将字符位置与之前确定的“仅远距离样条位置”的位置相匹配
- 字符的旋转由当前字符位置和样条曲线上更远的“手距离”点之间的自定义向量决定
-
-
向上/向下攀爬:
-
在 Up-Input 上,我运行一个输出距离浮点值的时间线,并在更新时,从我的距离中沿样条变量添加/减去该值
-
位置匹配计时器功能使字符位置/旋转与更新距离处的样条曲线保持匹配
-
-
摆动:
-
根据最接近角色的骨骼和根骨枢轴获得自定义的前向向量,以获得漂亮的弧线,而不管实际的骨骼/角色旋转如何
-
计算摆动力
- 这里发生了很多事情,但基本上我想要一个短暂的放松到全力以赴,并在角色向上摆动时减少力量,这样如果我继续朝那个方向按,我就不能以一个角度无限悬停
-
绳索对最接近角色的骨骼施加力,对目标点上方的每个骨头施加分数力,离骨骼越远,强度越小。这才是真正让秋千对我起作用的原因——在那之前,绳子总是会随着我挥得更高而开始弯曲,最终变得非常生涩和不稳定
-