Can't make WeldJoint work, please help.

Oct 27, 2011 at 5:20 PM

Hi guys. I will cut to the chase.

I have a player who has a body made rectangled shape(with cut corners of 1px width) and a crate that he can pick up. Crate has rectangle body(also with cut corners).

Both bodies are dynamic. Now what I need, is that when player will pickup the box, the box will be "glued" to the player's position, so whenever you move the body of crate will move exactly like the player. If the crate(that has body a bit in front of body of the player) will go into colision with some wall in front, the body of the player will not move further too.

Now I heard that this can be achieved by WeldJoint(to some degree, but some small movement is acceptable) that kinda "glues" two bodies together. I tried everything, but I just can't make it to work.

This is how I tried to do it. First I move the body of the crate using SetTransform method, and then I create a joint between those two boddies.

 

WeldJoint weldjoint = new WeldJoint(playerBody, crateBody, playerBody.WorldCenter, crateBody.WorldCenter);
world.AddJoint(weldJoint);

 

As far as I read I have to give the anchor points in the world space, not in local space(Vector2.Zero for example), and I do it like that. I tried with Vector2.Zero's too btw, with no result.

As far as you can see it's very simple, and I simply don't understand how it won't work. Also tried make the crate body with no collision categories just before it's picked.

I am using the XNARenderer so I can see the boddies and I don't see any problems with that. I tried linearJoint too just to check it, but also can't make it to work.

Am I missing something here?

 

cheers

Lucas

Oct 28, 2011 at 9:35 AM

Ok, I tried to do something similar(glue 2 bodies, same size, same position; one body is dynamic, the other kinematic) in other case in the game and DistanceJoint works perfectly, while WeldJoint makes the dynamic body fall(gravity applying here).

So this works ok:

JointFactory.CreateDistanceJoint(PhysicsWorld, _body, body2, _body.WorldCenter, body2.WorldCenter);

 

And this doesn't:

JointFactory.CreateWeldJoint(PhysicsWorld, _body, body2, Vector2.Zero, Vector2.Zero);      

Also tried like that, same result:            

JointFactory.CreateWeldJoint(PhysicsWorld, _body, body2, _body.WorldCenter, body2.WorldCenter);     

 

Can someone give me some clue here, what is going on?

Nov 18, 2011 at 1:48 AM

I had the same thing happen to me, but I just had to set FixedRotation to false on the crate. It then worked pretty well, except for the fact that the centroid of the character then snapped to a new position.

Nov 18, 2011 at 2:04 PM
Edited Nov 18, 2011 at 2:11 PM
thcsquad wrote:

I had the same thing happen to me, but I just had to set FixedRotation to false on the crate. It then worked pretty well, except for the fact that the centroid of the character then snapped to a new position.

Thanks a lot, that was it!!!

 

Wow, I would never thought of that(rotation must not be fixed for those joint types). Once I made them not fixed weld joint worked like a charm.

To keep it fixed, I just set Rotation to 0 in every update. Works nicely. It is strange however. I mean, why rotation must be not fixed for these joints to work? That doesn't make any sense.

 

Thanks a lot man!!!

Nov 22, 2011 at 6:27 PM

This is one of the joints I've had some success with.  Specifying local anchor points works, but it appears they both need to be relative to the same body.  Interestingly they both need to be relative to one body or the other: according to the constructor comments in WeldJoint.cs and my tests.  However, I'm still not sure how this ambiguity is resolved(?).  Try:

WeldJoint weldjoint = new WeldJoint(world, playerBody, crateBody, Vector2.Zero, playerBody.Position - crateBody.Position);
// or
WeldJoint weldjoint = new WeldJoint(world, playerBody, crateBody, crateBody.Position - player.Position, Vector2.Zero);

 

Feb 29, 2012 at 5:11 PM

Heh, cheers guys.  I managed to piece all the info here into a workable solution:
 (code is Unity3D, but should translate fine)

	public static Joint NewSolJoint( Body body1, Body body2 ){
				
		Vector2 sep1 = body2.Position - body1.Position;
		Vector2 sep2 = body1.Position - body2.Position;
		
		return JointFactory.CreateWeldJoint(m_world, body1, body2, sep1 * 0.5f, sep2 * 0.5f );
		
	}

 

 

So basically, the first vector is the distance from A to B, and the second is B to A - then both divided by two to stop the body centres snapping twice as far away as they should. Not quite sure why it's changed so much from Box2D, or why you have to explicitly state the relative positions, but there it is.

Note:  Sorry for the post necro, but as I'm still getting this issue, it seemed worthwhile posting an answer.

Apr 29, 2012 at 11:19 PM

Wow I'm glad this was discussed on the forums already.  I just ran into this the original issue while testing out WeldJoints myself.  After commenting out my character's body.FixedRotation = true, everything worked!  Well, ALMOST everything worked.  I still had to correctly position the sensor body as well as update its rotation around the player's character...