- Home /
Question on 2D joints and reaction force
Hello. I'm new to Unity and for starters making a simple 2D game where a player controls a bat. I don't want it to be too simple though, so I made controls like this: first a sum of external forces safe for drag is calculated, which are gravity and lift, where lift is as simple as k*(horizontal velocity)^2). Then if the input is (0,0), the bat applies a force to compensate these forces, which added with drag makes it stay in place. And if the input is not (0,0), it sees how much force it can spare to fly in the needed direction, added to the compensation force. There's some math there, but it's irrelevant, since the problem I have is with keeping the bat in place. So the impotrant part is this:
Vector2 externalForces = totalMass * Physics2D.gravity + lift;
where totalMass is just the bat's Rigidbody2D's mass, whuch equals 1. I've also set the gravity to exactly -10 for simplicity of calculation.
It worked perfect for just the bat, but I also want it to be able to pick up and carry objects like stones. So I created a stone object with mass of 0.25 and attached it to the bat with a fixed joint. They stay connected all right, so now I only have to compensate for the stone mass too. For that I set totalMass to 1.25. But that didn't work. With no input the bat slowly goes down, which means actual force pulling it down must be more than just gravity*1.25, so it can't compensate enough, at least that's how I see it. I tried different kinds of joints with different parameters, but the result is the same. Next thing I tries is instead of setting totalMass I used Joint2D.reactionForce. Now my code is like this:
Vector2 rf = joint.reactionForce;
Debug.Log (rf);
Vector2 externalForces = totalMass * Physics2D.gravity + lift - rf;
where totalMass equals 1 and as Debug.Log shows reactionForce returns (0, 2.4) when applying no input (also it's -rf and not +rf because it gives me a force pointing up while it really poins down, maybe it shows the force that affects the stone, not the bat?). And the bat still slowly goes down (must be even slightly faster than before, as it now trying to compensate 2.4 instead of 0.25*gravity which would be 2.5). I tried joint.GetReactionForce(Time.fixedDeltaTime) or joint.GetReactionForce(Time.deltaTime), but the result is the same.
Is there something I am missing? Some other force in action?
Experimenting with this matter futher I've tried something totally random like:
Vector2 externalForces = total$$anonymous$$ass * Physics2D.gravity + lift - 1.1f * rf;
and, to my surprise, it actually worked. At least as many digits of position.y as Debug.Log gives me stay the same over time. It also works with different masses for both the bat and the stone. The only problem remaining is that sometimes after collisions, reaction force gets stuck on numbers that bigger than just gravity (like (0, 2.6) for a 0.25 massed stone) which makes the bat try to compensate for more than there really is and as a result go up when it is supposed to stay in place. It fixes itself after another more lucky collision where it doesn't get stuck and returns to usual (0, 2.4).
With how surprisingly good it works, It does look like a workaround, and I would still like to know what would be the right solution. And if somehow this IS the right solution, I'd like to know why it is, where does the 1.1 coefficient come from?
Your answer
Follow this Question
Related Questions
Adding a force to RigidBody2d - Velocity returns 0 1 Answer
Set targetjoint2d anchor position at mouse position in 2d 0 Answers
Set connected Rigidbody 2D to a WheelJoint2D via script. 0 Answers
How to make rigidbody move with another rigidbody respecting physics? 1 Answer
How to prevent colliders from intertwining when using DistanceJoint2D 0 Answers