- Home /
What is the best way to Push or Pull an Object?
Hello,
I am currently trying to get a working script for pulling and pushing objects in a 2D game.I have heard there are several ways to do this. At first I was using the script found in the documentation, but I realized it only works for pushing objects and not pulling towards you. Then I came across making your character the parent of your game object. The following is my script atm.
function OnControllerColliderHit (hit : ControllerColliderHit) {
var body : Transform = hit.transform;
if(body.gameObject.name == "Crate"){
if (Input.GetButton("Action")){
body.transform.parent = transform;
body.rigidbody.isKinematic = true;
}
else {
body.transform.parent = null;
body.rigidbody.isKinematic = false;
}
}
}
I am having problems using this though. First of all, If I collide with the gameobject and then press the action button, (Hence my velocity is zero), my character will not be able to move at all. On the other hand if I hold the action button and collide with the gameobject at a velocity it will start moving with my character. Second, If I jump on my gameobject and click the action button, it will become the child of my character following his movements. How can I avoid this from happening since the character should only be pulling/pushing if he is on the left or right of the gameobject and not on top of it.
I have also read that you can do this by creating a joint that will attach the game object and the character together. I am wondering though if the joint method could be used if I am not using rigidbody as my controller. Currently I am using The platform input controller script along with the character motor.
Any Help is appreciated. Thank you very much.
it's exceptionally difficult to do this well.
can you simply state WHAT YOU ARE TRYING TO PUSH?
there is a big difference in meaning between "pushing a car as if out of petrol" and "pushing a pendulum" and so on.
Well I am just trying to move a box at the moment. But I may be trying to push logs later in the game. The objects that I try to push are similar to the ones found in Limbo. If it is possible for you to explain what is the main difference if I am moving a car or a box it would be great also.
Thank you for your reply.
So this box, what is it ? is it 2d, 3d, is it a rigidbody? is it a collider?
what is it ON, is it sitting on the ground, or ??
I'm sure someone can help if you give more info.
Nobody knows what you mean by "Limbo", post a small image if you like to explain.
Posting a quick small screenshot of your game, your editor, would be hugely helpful
I am just working with cubes and planes for now. As I stated this is a 2D game. The box is a cube on a plane. And it is a rigidbody, as shown in my script when I parent the object I set to is$$anonymous$$inematic to true. Hope this is enough for you to help.
Thank you.
Answer by Owen-Reynolds · May 24, 2013 at 02:25 PM
Two parts: how to know what to pull, and then pulling it. There might be a few ways to say "I want to pull this." For example, clicking on a crate. But, to go with what you have, bumping a crate selects it. The standard trick is to have a variable, maybe thingToPull
which will be set on a bump, and will be nothing (null) if we aren't pulling anything.
Then, once we have thingToPull
(no matter how we got it,) we can have Update move it around.
I'm using C#. Finding out what they want to pull, using your first script modified:
Transform thingToPull; // null if nothing, else a link to some pullable crate
void OnControllerColliderHit(ControllerColliderHit hit) {
if(hit.transform.name=="Crate") // NOTE: tags checking may be better
thingToPull = hit.transform;
}
Then the player's Update can drag it towards you. Notice I'm being cute here in a few ways. You lose it if it gets beyond 50 meters; it stops when it gets within 3 meters, and it gets pulled harder as you get further away.
if(thingToPull!=null) {
Vector3 D = transform.position - thingToPull; // line from crate to player
float dist = D.magnitude;
Vector3 pullDir = D.normalized; // short blue arrow from crate to player
if(dist>50) thingToPull=null; // lose tracking if too far
else if(dist>3) { // don't pull if too close
// this is the same math to apply fake gravity. 10 = normal gravity
float pullF = 10;
// for fun, pull a little bit more if further away:
// (so, random, optional junk):
float pullForDist = (dist-3)/2.0f;
if(pullForDist>20) pullForDist=20;
pullF += pullForDist;
// Now apply to pull force, using standard meters/sec converted
// into meters/frame:
thingToPull.rigidbody.velocity += pullDir*(pullF * Time.deltaTime);
}
}
At the end, it just adds to velocity. Lots of guys prefer an AddForce. 10 might be a little high for the pull, but it helps to use numbers that are too big when testing, so you can see it's working.
Thanks a lot, this is really helpful. For how to know what to pull I deciding using raycasting.