Search Unity

Grappling Hook

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

  1. groovedude

    groovedude

    Joined:
    May 28, 2009
    Posts:
    48
    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 I...as there are needed improvements...

    PROBLEMS:

    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

    groovedude

    Joined:
    May 28, 2009
    Posts:
    48
    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

    ColossalDuck

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

    groovedude

    Joined:
    May 28, 2009
    Posts:
    48
    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

    amunity

    Joined:
    Dec 3, 2009
    Posts:
    49
    its very nice

    but
    how to use mouse Aim
     
  6. groovedude

    groovedude

    Joined:
    May 28, 2009
    Posts:
    48
    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?
    ==========EDIT===========
    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.
    =============================

    @Amunity
    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:
    http://forum.unity3d.com/viewtopic.php?t=1378&highlight=grappling
     
  7. groovedude

    groovedude

    Joined:
    May 28, 2009
    Posts:
    48
    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).

    ==============EDIT===========

    I changed from a force thrown grappling hook to one positioned from linecast intersect data...no 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

    amunity

    Joined:
    Dec 3, 2009
    Posts:
    49
    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)

    Thanks
     
  9. groovedude

    groovedude

    Joined:
    May 28, 2009
    Posts:
    48
    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!

    http://unity3d.com/support/documentation/ScriptReference/Input-mousePosition.html
     
  10. raybarrera

    raybarrera

    Joined:
    Nov 20, 2010
    Posts:
    207
    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):
    1.  
    2. var pController: CharacterController;
    3. private var hooked : boolean = false;
    4. private var GrapplingHitPoint;
    5.  
    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;
    21.            
    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. }
    32.  
    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

    dajver

    Joined:
    Dec 9, 2012
    Posts:
    1
  12. YoloJoe

    YoloJoe

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

    Pixel-Sword

    Joined:
    Apr 13, 2014
    Posts:
    30
    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

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    wouldn't be expecting a response...
     
    YoloJoe likes this.
  15. Feartheway

    Feartheway

    Joined:
    Dec 12, 2017
    Posts:
    92
    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.