- Home /
Grapple and swing/pull mechanic
Hi all
I need to implement a grapple/hook mechanic into a game I am making and have looked around various forums as to how to do so but am still a bit stuck when it comes to the actual coding. I have borrowed elements from here: http://forum.unity3d.com/threads/36503-Grappling-Hook but am not sure how to get it working how I want. So far I have an object called shooter attached to the hand of the player model. When the user pushes 'g', the shooter shoots out and gravity is applied so that it behaves realistically. after 2 seconds, if it hasnt hooked onto anything, it returns to the characters hand position and gravity is removed so it follows properly. This part I have almost working as I want (except for some vector 3.lerp problems which I would also appreciate help with). What I want to do is if the grapple hits a grapple point, it stays and the character swings like a pendulum until they push a button to jump off. this could be achieved through spring joints somehow but not sure how to implement properly. If the character was to push up, they would move up the rope to the grapple point, which would be positional transforms. The game is 2D based so only need to move in the x,y directions. So far this is what I have attached to the shooter object:
var shootForceX=0;
var shootForceY=0;
var shootForceZ=0;
var smooth = 5.0;
private var hooked : boolean = false;
rigidbody.useGravity = false;
function Update ()
{
if(Input.GetKeyDown("g"))
{
rigidbody.useGravity = true;
//...shoot the spawned grappling hook with the forces set in the variables
rigidbody.AddForce(shootForceX,shootForceY,shootForceZ);
if (hooked == false)
{
returnShooter();
}
}
}
function returnShooter() //returns the shooter to the hand position
{
yield WaitForSeconds (2);
rigidbody.useGravity = false;
rigidbody.velocity = Vector3(0,0,0);
rigidbody.AddForce(0,0,0);
transform.localPosition = Vector3(0.0f, 0.0f, 0.0f);
//transform.position = Vector3.Lerp(transform.position, transform.localPosition , Time.deltaTime * smooth);
}
Answer by 8r3nd4n · Feb 06, 2012 at 03:24 PM
I have added some more and have some functionality working but it still does not behave how I need it to.
Once again, this script is attached to an object (grappling hook) that is parented to a character models (puppet) hand. it fire from the hand alright but still cant get the movement of the character right after that. I think the best thing would be to have a hinge/joint that when the player hits a grapple point, the hinge is enabled and they swing like a pendulum under the grapple point until a button is pressed and the hinge is disabled. When I have tried this, I cant seem to get the hinge to disconnect from the player and to attach it to a different grapple point. Because I am using a character controller, the physics are a real pain since adding the rigid body and gravity to the puppet causes it to go crazy.
Another idea I had was that the puppet could ping pong between 2 vector3's when on a grapple point until a button is pressed and they jump off, but am unsure also if this can be implemented.
var shootForceX=0;
var shootForceY=0;
var shootForceZ=0;
var smooth = 5.0;
var isShooting = false;
var isHooked = false;
var timeShot = 0;
var grappled = true;
private var GrapplingHitPoint;
public var swingPoint : Vector3;
function Update ()
{
if(Input.GetKeyDown("g") && !isShooting)
{
rigidbody.useGravity = true;
rigidbody.AddForce(shootForceX,shootForceY,shootForceZ);
isShooting = true;
timeShot = Time.time;
}
if(isShooting)
{
if(Time.time > timeShot + 2)
{
isShooting = false;
grappled = false;
retracting = true;
}
if(!isHooked)
{
returnShooter();
}
if(grappled)
{
IsSwinging();
}
if(retracting)
{
returnShooter();
}
}
}
function IsSwinging()
{
bob = GameObject.Find("Puppet");
//move the puppet to the grapple point
//maybe mathf.pingPong can make the character keep moving back and forth
bob.transform.position = Vector3.Lerp(bob.transform.position, swingPoint+ Vector3(6,-1,0), Time.deltaTime * smooth);
}
function returnShooter() //returns the grappling hook to the hand position
{
yield WaitForSeconds (0.5);
rigidbody.useGravity = false;
rigidbody.isKinematic = false;
rigidbody.velocity = Vector3(0,0,0);
rigidbody.AddForce(0,0,0);
transform.localPosition = Vector3(0.0f, 0.0f, 0.0f);
}
function OnCollisionEnter(collision : Collision)
{
if(collision.gameObject.CompareTag("GrapplePoint"))
{
print("HitGrapple");
isShooting = false;
colliding = true;
rigidbody.isKinematic = true;
grappled = true;
swingPoint.x = collision.transform.position.x;
swingPoint.y = collision.transform.position.y;
swingPoint.z = collision.transform.position.z;
//This gets the character object...
bob = GameObject.Find("Puppet");
//wait before returning the grappling hook to hand position
yield WaitForSeconds (1.5);
returnShooter();
}
}
Answer by josetgg · May 21, 2013 at 03:39 PM
Don´t use character controller, from my personal experience character controller only works properly when used on a game with very few physics or not very complex physics, and grappling hook physics falls out of that category.
I would recommend a rigidbody with out a character controller, and you can turn kinematic on and off depending if you want physics to be applied to it or not.
As for the swinging, you either achieve it with joints or fake it completely. To fake it you could try and use transform.RotateAround. This function rotates a transform around a point and an axis a given amount of degrees per frame. Using this function could involve a bit of math to get the rotation speed properly and simulate a pendulum properly but it could work.