Prototyping: Grappeling Hook
Written by Omer Keidar - CTO & Game Director at Scarlet Genesis
Our playtest feedback unanimously indicated that RoBo's movement needs to be more interesting.
We decided RoBo's entire movement system needs a rework. Tomer's task was to prototype this, and he will tell you about it in a future post.
Today I want to introduce you to the grappling hook feature we also decided to add to RoBo's toolbelt, to enhace his traversal abilities.
This post will be technical, and in the end, I'll share some more options we are considering for the grappling hook.
I thought it would be nice to share my prototyping process with you.
So first things first, I started with defining the grappling hook mechanic.
Why do we need a grappling hook? We want RoBo's traversal abilities to be more fluid and diverse. Adding a grappling hook would let us combine it with the level design to create more traversal options.
Because we are a toy in the human world, we will grapple with known items and thus repurpose them in our minds (a doorknob is not a means of going through the door anymore, but on top of it, for example).
We want the movement to be easy to use and predictable. So I think the best option, for now, is to have it shoot a projectile and pull RoBo toward the grapple point (like Batman's grappling gun).
If there are several grappling points in front of the player, the system should pick the one closest to where the player is looking.
To let designers (Tomer and myself) have a degree of freedom in grapple points allocation, we want to create a system that allows us to add grappling points to existing entities.
So far, we have defined the following:
Easy to use (for players).
Easy to place (for designers).
Shoots a projectile to the grapple point.
Pulls RoBo towards the point.
Chooses the closest point to where the player is looking at.
Now I'll start prototyping.
Be mindful that this is a prototype, so it will be better designed later. For now, we just want to check if this feature is worth investing time in.
To satisfy definition #3, I decided to make the grappling point a scene component. This way, we could add several grappling points to actors.
I created an empty scene component blueprint named BP_GrapplePointComponent.
Because we have to select the closest point, I want each point to "ask" the grappling system if it fits to be the focused point. So I created an interface for the grappling system and named it BPI_Grapple:
RequestFocus and ClearFocus get a BP_GrapplePointComponent reference as an input. I will implement the functions later.
Grappling Point Component
Back in the BP_GrapplePointComponent's BeginPlay event, I scan the owner actor for a sphere collision that would be our grappling interaction area trigger. Once the player is inside this area, we will start calculating the required conditions for grappling. The lower part of the begin play is an offset to the grapple point that I added much later. Ignore it for now.
When the player overlaps or stops overlapping with the sphere, I try to get the component that implements the BPI_Grapple interface from the owner. If it's successful, I enable the tick function to check if all the conditions are met.
In case we want to add a UI indicator that will show the player that there is a grappling point here, but they need to get closer, I added a "range" parameter which is the range we can grapple from (so the sphere will trigger the UI and when we get in range we could grapple).
Also, because we want to ensure we are looking at the point (in case there are several), I added a calculation of the player's look angle in relation to the grapple point.
If the conditions are met, I use the interface to request focus. If not, I use it to clear focus from this point.
Testing the component
Before I move on to the grappling component, I want to ensure my calculations are good.
I created an actor and called it BP_GrapplePoint. I added a mesh and a simple widget that shows how close we are to enabling the grapple point via a progress bar (this is completely optional). Finally, I added the grappling point component and to it a sphere collision.
The billboard is just for in-editor visual representation.
I added overlap events to the same sphere collision just to toggle the widget visibility and to set a flag to check the conditions and update the UI.
And in the tick event, I checked the conditions and updated the UI accordingly. I also printed all the values to the screen.
I placed 2 of these actors on my prototyping map:
And let's hit play:
looking too far to the side, the bar is yellow and not full.
Looking closer to it fills it up and makes it blue - ready to use.
OK, this works! On to the grappling component!
I created an actor component, set its "StartWithTickEnabled" to false, and configured it to use the BPI_Grapple interface.
The first function I implemented was the RequestFocus.
If we are not ticking (which means we are not currently grappling with anything) set this new grapple point as the focused point. Unless we are already focused on a point, in which case we will try to pick the best target according to the angle that the player is looking at:
Next up is the ClearFocus, which is very straightforward:
Now the StartGrappling. during implementation, I figured it would be nice to see actual rope fires from RoBo, so I took a detour and created the grappling hook itself. I'll show it afterward.
So if we are not currently grappling and have a valid grapple point focused, we spawn the hook and configure it to attach to RoBo's arm. Then, we launch RoBo in the air (so he does a little jump before grappling) and activate the tick function (which has the movement logic).
In the tick function, the main idea is to set RoBo's velocity for each frame until he reaches the point. Then, we will launch him forward a bit. We would also rotate RoBo to face the target and make him play a little montage:
Here we play the montage, and when we lose our focused target we will stop ticking and reset the DoOnce of the montage.
Then, setting RoBo's velocity and rotating him to the target:
Finally, if RoBo arrives close to the grapple point, we will stop the montage, Launch RoBo, stop ticking, destroy the grappling hook, and reset everything.
And, lastly, bind the input to the start grappling function (this is not the best way to handle input, but that would be refactored when I'll do a design pass on this feature).
So everything is set up. I still need to show you the grappling hook and the offset point.
The grappling hook is a simple cable and a static mesh where we attach the end of the cable to RoBo:
Just need to detach on destroying the actor so RoBo won't get destroyed as well.
And now, the offset point.
Offset Point Component
The offset point is just a scene component. I created it because sometimes I want the grappling point to be somewhere, but the mesh it is on doesn't provide a good climbing point, so this offset would end up being the actual point that RoBo travels to. This way, we can set the grapple point at its most pretty location and add a little offset to RoBo's destination (so we can grapple on top of things).
to calculate the final position, I use this:
Let's put this to the test:
Need to handle collisions and LOS, but it works!
More options we are considering to add to the grappling hook:
Pull certain objects toward RoBo.
Strip shields from enemies.
Pull RoBo on top of bigger enemies
We hope this post is helpful for you. If you have any questions or suggestions, feel free to contact us. We’d love to know what you think.
Want to be a part of a live game development process?
Get motivation and be part of a game dev and gamers community?
Join our Discord channel, where we go live while working, share UE5 tips & tricks, industry news, art, and just chill & play games (: