Grappling Hooks


A learning journey

Goals, inspiration and planning.

The goal for this project is to, within the time constraint of 5 weeks at 50% workload, develop a 3D grappling hook mechanic. The goal is for the player to swing freely through the world similarly to the game Floating Point, but in 3D.


The first stretch goal I have is for the rope to cling around corners, reduce the rope length and increase speed proportionally like Floating Point instead of just snapping like it probably will in first iterations.


The second stretch goal I have is for the players swing to be affected by moving objects.


As I will be developing my specialisation along side my website, this page will take on more of a weekly blog where I recap my progress, pitfalls and other perplexions.

Floating Point
Floating Point
The game Floating Point, published and developed by Suspicious Developments, used a 2D grappling hook similar to the idea I had for a 3D grappling hook.

Week 1

During my first week I focused mainly on website building, researching, planning and preparation.

I feel like I am on schedule so far. I've found a good open-source player controller script with plenty of values to tweak and build more upon.

The websites general structure is coming along quite well, as I'm feeling satisfied with the landing page and most of my portfolio pages.

Week 2

During my second week I sadly didn't progress as much on the project as I would have liked. This was due to unforeseen circumstance that forced me to spend almost the entire week creating, iterating and getting my resume peer reviewed.

I have fallen a little bit behind schedule but I think it will be manageable, but it will perhaps affect my final stretch goal.

Week 3

3rd week done! I found a tutorial on a basic grappling gun by the same developer who published the character controller script I am using. I followed it and made sure I understood it 100% as it was a big part of my project.

It works by using Unity's SpringJoint component in conjunction with their LineRenderer component.

I will continue working heavily in this script to attain my first goal: Corner wrapping.

Week 4

I feel overjoyed thanks to the progress I've made this week!

I have gotten cornerhugging/wrapping to a point where I am very pleased with the results! At the time the rope can wrap around corners and unwrap again, affecting the length of the remaining rope in turn affecting the momentum of the player.

One of my issues at the time is the rope "cuts corners" when wrapping around a box. This means that the rope draws through the box meaning you can't see the rope against the box exterior and therefore removing a bit of the magic. I'm considering solving this by having a seperate lists of grapple points that the physics use and a list of drawpoints that the linerenderer uses. The drawpoints will be offset with the reverse movement vector of the player from when a new grappling point was created.

The following screenshots were added later thus the anchor class from the following week is already implemented, but I thought showing the code behind the grappling and wrapping would give more insight.

Week 5

Dawn of the final week.

This week was all about wrapping up(haha) features and I feel immense pride over the project's outcome.

When I tried introducing moving blocks I realized that while the blocks themselves moved, the anchorpoint of the SpringJoint did not. It was at this point obvious I'd have to refactor my way of storing grappling points.

Thus the Anchor class was born which gives me a handy List<Anchor> to iterate through. This gave me the possibility to solve last weeks problem where the rope would cut into the object its wrapping around making the rope mostly dissapear. The grappling point is the actual connection point for all physics comparisions and checks, the drawing point the grappling point - the players movement since the last frame. The drawing points are what I feed to the Linerenderer to draw the rope.

If the anchors were to move along with the moving blocks, they would naturally have to be updated aswell. Thanks to the Anchor class also saving what gameobject they've hit, I could check if said gameobject had a MovingBlock script and if so add it's movement from since the previous frame.

Minor additions this week was also the previously mentioned MovingBlock script which lerps between 2 positions, a "Reel" feature to allow the player to shorten their current SpringJoint and a Killplane/Checkpoint combo!

Results and Conclusion

Results!

I am overjoyed with how this turned out! There has been some gameplay from my 2 roommates and they've best described it as "fun". I have to agree with them, it has been times where I tried to search for unintended behaviours but lost my self in just swinging around.


The gif to the right shows off my finished product, I tried my best to display what an example level could look like however I feel like my level design skills aren't on par with my vision. The best thing according to me is just to have fun and swing around to build momentum in the "Random blocks everywhere scene" so a bit down I've included a gif where I do some slick tricks in said scene.

In both of these footages I've made the rope thicker and coloured it red for visibility's sake but in retrospect it might be better to keep it that way for accessibility.


A feature I got recommended was for a pulley-like feature.The feature would work like that if a player would attach to a moving block and then wrap around a corner, the moving block would adjust the length of the rope. Should I implement this I would simply calculate the total length difference before and after updating all non-active anchors and add/subtract the springjoints maxdistance accordingly. However I decided that while it could make for some cool level segments, I feared that the wow-effect from such moments would be outweighed by the irritation players would feel if it happened unintentionally.


I managed to reach all of my goals in the end even though my planning got a bit helter skelter but that leads to the big question everyone seems to have at the end of a project...

What would I do with another week?

Should I've get an extra week of development time I would ask a Level Designer colleague to design a basic level with me and tweak some player values, I think as of now the gravity is a bit undertuned and my test level doesn't fully showcase my vision. 

I have a bug that I've almost remedied, the bug makes the rope unravel to the previous point when it shouldn't. It's visualized to the left. When I'm trying to wrap around a small enough object so that the rope can't wrap around both upper corners(along the black dotted line) the rope thinks that since it can see the previous anchor, it should unravel to it(along the red dotted line line). This was remedied by taking the dot product between the current ropevector and the vector from the current anchor to the previous one and comparing if the vectors are paralell. It eliminated 99% of the cases where it happened but on small enough objects it still occurs, I would've liked to squash the bug completely.

I feel like the next step for the feature is for the rope to be able to tangle into itself but that would need more complicated wrapping/unwrapping code than as of right now.