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.
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.