Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Grappling Hook

Discussion in 'Scripting' started by groovedude, Dec 8, 2009.

  1. groovedude


    May 28, 2009
    Attached is a work in progress on a grappling hook.

    Basically a "shooter" object fires a prefab "grapplingHook". The grappling hook has a script that draws a line between the two. Another script moves the position of the shooter when the prefab hits a rigidbody object.

    Nothing fancy just used primitives. Code is well documented.

    I hope posting this generates enthusiasm from better coders than there are needed improvements...


    1. I couldn't get a nice gradual lerp between positions to work.

    2. It might be nice if there were some swing and bending to the line.

    3. I could not get the line to draw if I made the shooter object a rigid body.

    4. On firing the grappling hook there seems to be some ugly line draw that flashes for a split second if you really pay attention to the screen. Not sure if that will show up in a build or not...didn't take the time to find out.

    File is a Unity Package created on PC, not sure if that means Mac users won't be able to use it...

    Attached Files:

  2. groovedude


    May 28, 2009
    Hello my silent, but adoring fans...attached is grapple2.

    It is now working with rigid bodies but I could not get a springJoint working on the grappling hook and shooter. To get around using springJoint's I wonder if its possible to just (temporarily) move an objects center of gravity (to the swing or hinge area) and let physics take it from there...

    There are some grappling hook scripts here and there on the forum but I'm trying to roll my own (although I'm certainly open to your help). It's been a good learning exercise.

    Attached Files:

  3. ColossalDuck


    Jun 6, 2009
    Hey man, good job. This is really neat. :D
  4. groovedude


    May 28, 2009
    Grapple version 3.0 time.

    I gave up on springJoint's, so now I'm faking it with addForce's. Scene "Test3" attached has shooter "swinging" along 2.5D style. Really the addForce's just make him do a "swimming Super Mario" but because I'm using my grappling hook with lineRender it looks like a fairly decent fake.

    I can't figure out how to prevent the grappling hook from repeatedly firing, so if you keep hitting the spacebar it starts to look something like an upside-down octopus--maybe something interesting could be done with that, who knows.

    Probably the last update on this for awhile...

    Attached Files:

  5. amunity


    Dec 3, 2009
    its very nice

    how to use mouse Aim
  6. groovedude


    May 28, 2009
    I might be able to get this working with springJoints, however whenever I add the springJoint component to a prefab Unity forces the the connected body to none and refuses to allow you to drag an object into the requester. Maybe this is a bug or maybe there is a reason why? In any event I've tried to set the connected body with attached code, but my code must not be correct. Anyone know how to set the connected body with code?
    Oh snap! I figured it out. Place a springJoint component on an object that will be the "anchor" prefab from which another object dangles. Then make a script with this code and also put this on your anchor prefab.

    Code (csharp):
    1. function Update () {
    2. bob = GameObject.Find("Cube");
    3. bobRigid = bob.rigidbody;
    4. var spring : SpringJoint = GetComponent(SpringJoint);
    5. spring.connectedBody = bobRigid;
    6. }
    Now to put it all together...Keep in mind that springs set the minimum distance at instantiation. If you are like me this can really throw your thinking about springs off. So you can't get springs to pull an object toward another...well you can, but the object you want to be pulled needs to be at the closest proximity allowable to the "anchor" doing the pulling at instantiation. The minDistance variable makes it seem like you could programmically alter the true minimum distance, but that is not true.

    Instead of just using forces on the grappling hook that is triggered by the spacebar you'd need to use raycasting and some sort of mouse control code.

    This link may help you get started:
  7. groovedude


    May 28, 2009
    OK, have a look and see the grappling hook in action:

    Grapple Hook

    This is using a joint spring.

    Obviously it is still not perfect. The grappling hook occasionally goes through the geometry. I read that this can happen when an object goes faster than the rigid body physics listener.

    The grappling hook is being thrown with addForces from a Update function. As you can see in the packages from earlier posts. Any ideas how to correct for this?

    One idea is to rewrite the grappling hook thrower by using a raycast to get a location for the grappling hook to go, then use a lerp to get there. This way velocity will not be a factor. However, this will change the gameplay as the hook will always hit something (if there is stuff around).


    I changed from a force thrown grappling hook to one positioned from linecast intersect more velocity issues. I figured out how to Lerp so that the grappling hook can more slowly get from the shooter to its destination but I haven't implemented it. I found some math on animating arcs and might use that instead.

    Make sure you use ".point" to get the positon of a raycast or linecast intersection instead of ".position". Position will give you the center of the object you hit, instead of the exact point you hit. I kept thinking raycasting wasn't working right, switched over to linecasting before I figured out what the problem really was...user error...

    Anyway, the web demo has been updated. Unity rocks my socks, goodbye Flash...
  8. amunity


    Dec 3, 2009
    i am following your instruction since past 4 or 5 week but didn't solve this right now m stuck can you show me how to do that (mouse Aim)

  9. groovedude


    May 28, 2009
    I haven't done it myself, but basically what you would want to do is something like this:

    1. On mouse down or fire button

    2. Produce a linecast

    3. The origin of the linecast is your player object, the direction would be the mouseposition (see link below).

    4. Get the hit point vector3

    5. Draw a line, the origin is your player object the end point is the hit point vector3. Also at this time instantiate the grappling hook at the hit point vector3

    5. Make your character jump up a bit using add force

    6. Create a spring joint that connects the grappling hook to the player object

    7. Viola, ce tres bon!
  10. raybarrera


    Nov 20, 2010
    I'm a little late to the party, I know, but I'm working on a hook of my own atm, and I found your tutorial.

    First, let me post where I am at:

    This code is attached to the "barrel" of the character which can aim straight up, 45 degrees up, 0 degrees forward, or 45 degrees down.
    Obviously, going with the spring joint method, I can get rid of the gravity bits, but they're explained in the comment lines.

    Code (csharp):
    2. var pController: CharacterController;
    3. private var hooked : boolean = false;
    4. private var GrapplingHitPoint;
    6. function Update () {
    7.     var gPoint : RaycastHit;
    8.     //Getting input from player and unhooking him if he's already hooked.
    9.     if (Input.GetButtonDown("Fire2")  hooked == true){ 
    10.         hooked = false;
    11.         Movement_revised.gravity=20;
    12.         //setting gravity back to normal
    13.     }
    14.     else if (Input.GetButtonDown("Fire2")){
    15.     // Raycast from the barrel (which has an aim feature that follows the mouse position) forward 10 meters    
    16.     //If the player isn't already hooked, we'll go ahead and create the raycast.
    17.         if (Physics.Raycast (transform.position, transform.forward, gPoint, 10.0)  hooked == false){
    18.             GrapplingHitPoint = gPoint.point;      
    19.             print("Hooked!");
    20.             hooked = true;
    22.         }      
    23.     }
    24.     //the actual funcitonality of the hook goes here based on whether the player is hooked or not.
    25.     if (hooked==true){     
    26.         //changing gravity to avoid the player falling to fast after he has reached the end of the raycast
    27.         Movement_revised.gravity=4;
    28.         var smooth = 1.0;      
    29.         pController.transform.position = Vector3.Lerp(pController.transform.position, GrapplingHitPoint,Time.deltaTime * smooth);
    30.     }
    31. }
    I basically have your steps from 1 - 5 1/2. It shouldn't be too hard to implement the rest of the steps to what I already have, but I have these questions:

    Do you draw the line using lineRenderer?
    When you say "instantiate the hook" are you referring to the same linerenderer?
    I couldn't find an "enable" variable for the spring joint, do you instantiate that as well? If so, do you destroy it whence you're unhooked?

    Thanks in advance :)
  11. dajver


    Dec 9, 2012
  12. YoloJoe


    Jan 20, 2016
    Any progress on this the last 6 years @groovedude?
  13. Pixel-Sword


    Apr 13, 2014
    I would also really love to know if any more progress has been made, this was a really interesting project that I would like to see some more progression on.
  14. LeftyRighty


    Nov 2, 2012
    wouldn't be expecting a response...
    YoloJoe likes this.
  15. Feartheway


    Dec 12, 2017
    i made a grapple gun for unity its open source c#, if you want to use it to do something special with it.

    it integrates with invector lite free controller. My next step is putting in a proper rope rather than a line renderer if anyone can help that would be cool. I think it will be something to do with splines.

    pastebin link in video description.