[SHARE] Blueprint-only Physics Rope System

[This is a long post, so I’m breaking it up into multiple parts]

For the past few months I’ve been working on my own little game - a hand-drawn 2D game with platforming and puzzles (although I don’t want to call it a platformer) - and I’ve been busy creating the gameplay elements and preparing for a “production gate”.

Eventually, my sight turned to adding ropes to the game, and suddenly the weeks flew by trying to figure out how, what, why, and how much of my sanity I was willing to sacrifice to get it working (spoiler: not an insignificant amount…).

There are a number of tutorials out there, but none of them either worked for all the things I wanted, or worked at all for me. There are certainly a lot more questions about the topic than satisfying answers.

After weeks and several failed prototypes, I’m finally happy with where I am at with my rope system, and since I learned so much from this and other Unreal communities, I thought I’d give back and break down how I created the rope system for my game.

The final result can be seen here:

I’m currently adding sound cues and tweaking the values, but you get the idea. I’m by no means an expert (as you can probably tell by me trying to do all this in blueprints) and I’m sure I made plenty of mistakes, but hey, it’s working for me… [HR][/HR]
[Goals]

I had a clear idea of the main features I wanted to include:

  • Modular, scalable and reusable
    I don’t want to create custom actors for every single rope. I want one actor with all the settings I may want to change and not worry about it
  • Smooth and natural swing motion anywhere on the rope
    I don’t want predetermined swing points. I want to grab the rope and be able to swing wherever I’m hanging
  • Free movement along the rope
    I want to be able to smoothly travel up and down the rope, even if the rope is in motion
  • Non-blocking, but responsive collision
    Since I’m working on a 2D game, I don’t want the rope to block the character when he walks past, but still have some reaction when the character brushes past
  • Stable and predictable
    By far the hardest part - physics are soooo touchy….

[Early Attempts]

The three main ways to create a rope in Unreal are cable component, skeletal mesh and a combination of physics constraints and collision volumes, each with their own drawbacks.
Cable Component: NOT SUITABLE AT ALL

  • No built-in collision
  • Only able to attach to either end
  • Too “stretchy”
  • Hard to apply precise swing motion
  • Climbing or swinging from anywhere along the rope requires tons of runtime calculations

Skeletal Mesh Actor: VERY CLOSE

  • Fixed size
  • Bad mesh deformation on greater bone rotations
  • Lots of calculations required for smooth and predictable climbing

Collision Volumes & Physics Constraints: CLOSE

  • Increasingly unstable at greater rope lengths
  • Some important settings not exposed to blueprints

[Components]

Both skeletal mesh and constraint/collision volume had some elements that worked great, and others that I wasn’t happy with, so I decided to merge their best parts and bend them to my will - muahahaha:

  • Skeletal Mesh with Physics Asset for the rope behavior
  • Spline Mesh for the visible rope (more on that later)
  • Actor BP to handle the rope logic
  • BP Interface to communicate between rope and character

I will break down each of those components in detail in future posts.

1 Like

[Skeletal Mesh Setup]

Using skeletal mesh as foundation kind of went against my “reusable, scalable” goal, but with a simple Maya script I can crank out ropes at various sizes and bone distances in no time, and I can live with that.

I created a joint chain and skinned a simple mesh to it - basically just a plane with an edge at each joint.
I will only use the skeleton and hide the mesh, but I need to have skinned vertex data so the bones import into Unreal.

I settled on bone distance of 20cm for the skeleton, and a simple plane with an edge at each bone for the mesh.

Using what I learned from lusiogenic’s great videos I recreated the physics asset with my own bodies and constraints.
It’s worth a watch, so I’m not going to retread how to set up the constraints and bodies.

It’s worth experimenting with all of the settings on both the bodies (capsules) and the constraints, based on your needs, but here are a few of the key settings for my purpose:

Bodies:

II_Body_Settings

  • Mass:
    This is a base value. The final value will be set in the construction script of the rope actor.

  • Linear/Angular Damping:
    These are the settings for my 10 meter rope. They are a lot higher than the default settings, but really help to stabilize the whole rope.

  • Type:
    I set all to simulated so I can attach either end in the Actor BP

  • Inertia Scale:
    Increased by 0.5 from default to help stabilize

Constraints:

Constraint Behavior:

  • Disable Collision:
    I don’t want the rope to collide with itself

  • Enable Projection:
    This is one of the most important settings to keep the rope stable

  • Projection Linear/Angular:
    Both are not exposed to blueprints, and can greatly increase stability, especially linear tolerance.

  • Linear Limits:
    Although I don’t want the bones to move, I found that setting the limits to “Limited” with relative high stiffness and damping to act much more stable than setting it to locked.

  • Angular Limits:
    Since I’m working in 2D, I only set the camera-facing axis to “Free” and locked the others.

  • Linear Motor:
    High values to make sure the rope doesn’t “explode” under high tension.

  • Angular Motor:
    Make sure I’m only using Twist&Swing (Sam Cooke, anyone?) and left the default strengths.
    I had higher values earlier, but the rope became rather sluggish. Not sure if I needed Max Force, but it didn’t hurt…

Timesaver: “Select All Bodies” and Edit>“Select all Constraints” can be used to quickly set select and set the values*

The last step on the skeletal mesh was to create a constraint profile and assign all constraints to it. This will be used in the Actor BP to initialize the skeletal mesh of the rope.

3b6b4668c44302b700d75aa88cf6f2a7af1a264c.png

Select NEW to create a new profile, select all constraints and assign to profile.

=======================================================================

[Rope Actor BP Setup]

The Rope Blueprint is a standard actor class.

II_Rope_BP_Components

  • Rope Skeletal Mesh:
    Skeletal Mesh Component. Will be set in Construction Script

  • Top Anchor:
    Physics Constraint. Used to attach the top of the rope, or detach when needed - that’s the thing I triggered at the end of the video.

  • Rope Sounds:
    Audio Component that plays impact and swing sounds. I’m still working on the sfx part, so things may change

The Physics Constraint has similar settings to the ones on the Physics Asset of the Skeletal mesh, but I didn’t set any linear limits.

The skeletal mesh component has been left mostly at default, but I changed the collision settings a bit:

6efe2c3fa32ce4c781cfc0233f02b0e0ba05b5e4.png

I’m using Hit Events to trigger the SFX, and I created a custom collision preset to apply to my rope.
It’s near identical to the PhysicsActor preset, but has Pawn set to Overlap and my custom trace channel RopeTrace set to block.

Why, you ask?
Because character movement has a hard-coded collision response to physics bodies, and while it looks and works great, it also means that any rope in my 2D game will block my character. What I want is a slight collision response, like brushing past a soft object when I walk by, and something that gives me more control over the response per instance than the hard-coded values.
So I have to disable overlap events and check for any rope collsion with my own trace for objects and then generate my own collision response.

EDIT: Forgot to mention about the render settings

The last step for the skeletal mesh is to hide it in-game. I’m using the physics behavior of the skeletal mesh to drive a spline mesh - a spline point at each bone, spline mesh drawn along the spline and updated at runtime to keep matching the rope.
So, away you go…

7d0744b619fc3011aa14fb3e654c141c76e20697.png

=============================================================================

To make it easier to change rope settings per instance, I exposed a few parameters in the BP.
I like to keep things neat and easy to follow, so I grouped them in structs and made them “Instance Editable”.

II_Rope_BP_Exposed_Settings


Setup:

  • Skeletal Mesh:
    This is where I select which asset to use. Would have been great to have a slide to change the size, width, etc, but considering the much better stability of a skeletal mesh vs any other solution, I’m okay with that compromise.

  • Rope Material:
    Custom enum variable. This decides which spline mesh to use in the construction script, and selects the correct sound library.

  • Rope Scale:
    Determines the scale of the spline mesh. Most obvious effect is the width of the rope, but I’m also scaling the length to avoid stretching/squashing of the spline mesh.

  • Margin Top/Bottom:
    Custom limits to how close to either end of the rope a character can climb. I want to avoid clinging to just the very tip on a swing, for example.

  • Rope Lerp Speed:
    How quickly the spline/spline mesh updates to match the skeletal mesh (more on that later).

Physics:

Most of them will make more sense when I go through the function, so I’m gonna skip them here

  • Start Active?
    If I want to simulate physics at Begin Play or activate it later
  • Attach Start:
    If I want the rope attached to the “Top Anchor” constraint
  • Attach End:
    WIP, but I want to be able to attach the end point to other static or dynamic actors

[Blueprint Interface]

The final component is a Blueprint Interface to send things between rope actor and any actor that can influence it (mostly my player character).

II_BPI_Functions

  • Apply Swing Force:
    Sent from character BP to rope to apply swinging motion based on user input.

  • Grab Rope:
    rigger character to enter “rope mode”.

  • Add JumpOn Force:
    Character BP to rope, apply impulse based on characters velocity prior to rope grab.

  • Climb Rope:
    Based on user UP input, initialize climb (up or down)

  • Add Impulse to Rope/Add Climb Impulse to Rope:
    Similar to Add JumpOn Force - give the rope a nudge during collision, climbing, etc

  • Update Target Bone:
    A lot of the rope behavior is driven by the bone closest to the character, and I need to update which bone that is when the character climbs.

  • Reset Bone Weight:
    I’m adding the characters weight to the target bone, and this resets to default after the character left the rope or climbed.

  • Break Rope Anchor:
    Break “Top Anchor” constraint

  • Update Character Left Rope/Rope Has Broken/Notify Character On Rope:
    Notifies of state changes to trigger resets

Already running quite long - I’ll update Part III in the next few days.

3 Likes

** What’s that about a Spline Mesh?]**

You may be wondering why I keep mentioning a spline mesh, and not just go with the skinned mesh I already have.

For starters, I preferred the look of a spline mesh for my game.
Since I can use tangents to create a nice curvature, I can use less bones to create the rope and therefor less physics overhead.
Compare the result of a spline mesh and a skinned mesh with equal spline point/bone distances below - spline mesh wins hands-down.

01-spline_vs_mesh.jpg

Next - using a spline mesh makes it a lot easier to change the appearance of the rope per instance.
If I wanted to change e.g. the width of my rope using only a skeletal mesh, I would need to create a new mesh - more work, more room for error, more things to maintain.

I also found it hard to completely lock my skeletal mesh to the Y-Plane. Even after constraining whatever I could to my view plane, the skeletal mesh would still “wander” a bit or twist and would make keeping my character aligned tricky.
The spline mesh I’m using on the other hand only takes X an Z values from the skeletal mesh, so I can guarantee that it will always remain aligned on Y.
And last but not least, the spline is a great helper for positioning my character on the rope and assist in climbing.

It’s obviously more expensive since I’m using two different ways to do the same thing, but as long as I don’t spawn hundreds of ropes in my level, I don’t anticipate any issues.
[HR][/HR]
Alright, time to dig into the meat of the system.

As an overview, here is quick look at the logic behind my rope system:

Rope BP Construction Script:

Rope BP Event Graph:

Character_BP Event Graph (Rope behavior section):

As you can see - a lot going on there, and it’s full of custom functions, so I don’t think I can go through every single piece in detail.

In the next part, I will go through the behavior flow and explain the individual components, highlight my custom functions and what they do, and hopefully it will make some sense…

3 Likes

Hey, looking forward to see more! If you want me to remove my post, I can do that! I guess you want to keep your posts in order, but I just want you to know I’m very interested and looking forward to see more! Thanks!

It’s fine, you can leave the post :stuck_out_tongue:
I think My updates will stand out regardless, due to their length and pictures.
Been busy drawing animations the last couple days, but I’ll add another part tomorrow or the day after.

** Setting up the basic rope behavior ]**

Alright…let’s look at how to set up the rope to act like a rope. I’ll go through the basic setup of the rope actor all the way to a game-ready (passive) rope, and break down the climb and swing mechanics int he final update.

** Construction Script ]**

I set up a few custom functions that handle the setup based on a few literal variables and other user-set values grabbed from my setup structs.

(1) - Set End Constraints


Very simple setup. I check if I should attach the top of the rope (from details panel) and then either set the “TopAnchor” physics constraint to attach to the first bone, or not.
The variable “is Rope Legal” gets queried by my character to check if grabbing the rope should be allowed - I obviously don’t want to trigger climb or swing when the rope is falling or already on the ground.

The second pin of the sequence is for attaching something to the bottom end of the rope, but I haven’t added that part yet (if I’ll add it at all).

(2) - Setup Skeletal Mesh


Just grab the skeletal mesh variable from the setup struct and set it as the new skeletal mesh on the “Rope Skeletal Mesh Component”.
The component has a default mesh set, so if the user input is empty it won’t overwrite (which would lead to warnings at runtime).

(3) - Setup Skeletal Mesh


Nothing fancy, just grab the “Segment Mass (kg)” value from the setup struct and then loop through each bone of the skeletal mesh and assign that new bone mass.

(4) - Create Rope Spline

As a reminder, I set the skeletal mesh component to “hidden in game” and unchecked “visible”. This spline and the spline mesh created along it is what is seen in game.

I added an array to store my spline points, so first I clear that array in the construction script to be on the safe side.
I add a new spline component, store it for later reference and clear all points - I don’t want default points or their location because I want to rebuild it from scratch.
Then I get how many bones my skeletal mesh component has, and loop through to add one spline point at each bone.
Each point created gets added to my spline point array.

At the end, I store the length of the spline “at rest”. There can still be some stretch at runtime, so I want to know how long the rope is without physics acting on it.
I’m using “location at distance along spline” to match my player character to the rope, and when the rope is stretching that loses precision. To compensate, I have a function that compares default length to current length and for that I obviously need to know the default length…

(4) - Create Spline Mesh
(big picture - sorry about that…)


Now to add a spline mesh along my newly created spline…
First off, I grab the scale from the setup struct and convert and store it as a local variable.

I added a custom function (a) to find the dimensions of the spline mesh(es) I’m using.
The “Rope Material” enum in the setup struct has certain static meshes associated with each option, so I’m reading that enum, get the associated mesh, “get bounds” of that mesh and return the box extents. The way my static meshes are aligned, the X value represents the length.

next I’m doing some calculations to see how may times I can add that static mesh along the spline.
I’m using the “division (whole and remainder)” to get my number of segments, and add 1 if the remainder is greater than half of the static mesh length.
Now that I know how many segments I need, I recalculate the actual length of each spline mesh segment. Depending on the earlier “remainder” check, that means the spline mesh will either get stretched or squashed down a bit, but not more than 50%.

Now I start looping and add a spline mesh segment until I reach the end of the rope.
The custom function (b) checks for the current loop index and “Rope Material” enum and returns that static mesh to set each segment to. (I’m using three static meshes for each “Rope Material” type - 1 top end, 1 middle part, 1 bottom end. Index 0 selects top end, index “last index” selects bottom end, everything else selects middle part).

I set start and end position of each segment based on the segment length I determined earlier, and scale down the tangents to the same length.

Then set the scale of each end to the value calculated at the beginning, disable collision (don’t need the rope to do anything but look pretty, collision itself is handled by the skeletal mesh) and add each segment to another array.

** Rope Actor Event Graph]**

Now that I have the visual rope added, I need to update both spline and spline meshes to keep matching the skeletal mesh component.

Each custom function is similar to the ones used in the construction script, but instead of calculating and creating the elements, I loop through the arrays and update them.
The branch at the end checks if my player character is currently hanging on the rope, and if true, I calculate his current velocity. (I’m using “Set Actor Location” to match my character to the rope, so he doesn’t have his own velocity, and I need to know how fast he is swinging for the exit jump or drop)

Update Rope Spline


Fairly straight forward. I check if the rope is actually simulating (no point to update each tick if nothing changes…) and then loop through the spline points and update their location based on their respective skeletal mesh bone location.

You’ll notice here I didn’t grab the Y-location of the bones.
I found that the skeletal mesh still moves a bit in Y even though I specifically told it not to (silly teenager, never does what he’s told…), and since I’m working in 2D and need my character aligned to the viewplane, I decided to just ignore what the skeletal mesh does on Y and simple force it to stay flush.
If you are thinking of doing this for a 3D game, just ignore that part.

Update Spline Mesh

Here I’ll update the component length based on any spline stretch as a local variable, then loop through the spline mesh array and set location and tangents the same way as in the construction script.

Activate the Rope

The last step to make the rope act like a rope is to activate it.
(Not going into the sound part, I’m still working on that.)

At “BeginPlay”, I check if it should be active (from setup struct), and if true, assign the constraint profile (see post II - Skeletal Mesh Setup) and simulate physics.
If the rope is not set to active, I have a BPI function “Activate Rope” I can call that does the same thing.

To illustrate why I’m going through all this trouble to make a spline mesh and not just use the skeletal mesh as it is, here’s a simple side-by-side comparison of the two in action:

It’s not an earth-shattering difference, I admit, but I do prefer the spline mesh look. And in cases where the rope loops back on itself and collapses, the effect is even more pronounced.

[Project Settings]

One final thing I forgot to mention earlier is my use of sub-stepping.
Physics are quite touchy, and on elements like my rope that can receive a lot of force over a short amount of time, it tends to freak out, so sub-stepping is a great helper to keep the bones in line.

IV_substepping.PNG

So, sub-stepping is turned on, and I tweaked the delta time values to be basically fixed.
This part is still work in progress, but in my initial tests of capping the frame rates to 30, 60 and 120, this really helped to keep the rope stable and gave me consistent force for swinging.
(Before setting this, higher frame rates made the swing much more powerful than lower frame rates, and I obviously don’t want that kind of difference in behavior…).

BTW, if I’m making any major boo-boos, please do let me know. I’m learning as I go along, and I’m always happy to get some feedback.

1 Like

Hello. it’s incredible! I would be very grateful if you have the opportunity to duplicate the pictures from January 6th again. since they are not displayed

Heya all…

I’m still waiting for the forum update to be complete so I can re-edit the first few posts and fix the formatting and pictures.
Also got the last part still in the pipeline that will come eventually.
Still recovering from an inter-continental move, so might be a few weeks before I get to it.

1 Like

Hey, I just stumbled upon this thread because I’ve been trying to make a rope swinging for my system for the past week and I’m not even close. I’m making a game that’s based on jungle parkour (for my university application) and I wanted to have vines the player will use.

Your explanation was perfect, I understood everything you did, but I have some problems with the function that are not fully shown like: Prepare Avatar For Rope Grab, Calculate Collision Force, Match Avatar To Rope ( I suppose you take the target bone and set the player’s location and rotation to that bones’ transforms), Update Target Rope Distance ( here, I think you add the result of the timeline to the current position and verify if you got to the border of the rope, but I don’t know what did you put in the timeline, so I’m not sure) and the last one (I think) Calculate Swing Force (The player decay is calculated using the distance from the lowest point or spline point of the spline, right?).

Anyway, thank you so much!! Also, if your game is on steam or anywhere else, please drop a link, it looks awesome and I’m curious how is it.

Kinda late to the party, but this writeup has been immensely helpful while trying to make a similar system. Any chances we get the last couple parts, even if abridged? Thanks a ton.