I’m trying to create some space ship control physics. I want to implment a system whereby each individual thruster enacts a force on the ship at the position of the thruster. How can I do this?
I tried creating rigidbodies for the thrusters with colliders that cuold push against the ship’s frame collider, but doing that makes the colliders repel each other. If I tell them all to ignore each other, then the rigidbodies of the thrusters can’t push against the frame of the ship.
I know I could calculate the forces and torque mathematically, but is there a way to let the physics system do the work for me?
Yeah. I tried that, but that doesn’t work right. Imagine the beam of a ship is about 200m (the length is arbitrary,really; just imagine the ship is much longer than it is wide). If you have two engines at the back, mounted equally distant from the center line of the ship, but in opposite directions, when you fire both engines, the ship should go straight.
Using AddForceAtPosition() works for a few seconds, but then the ship starts twisting and turning unpredicatably. Even the documentation says that it results in unrealistic torque when the position of the force is not near the surface of the rigidbody Now, I imagine, by surface, it means either the collider ot the bounding box; it doesn’t matter. In both cases, the engines are not mounted near the surface, and so the force (which I would like to add to their actual position) can not be applied accurately without the weird torque effects.
I came to the conclusion last night that there isn’t a practical workaround for that flaw, so I’m probably just going to write my own physics code to handle ship control physics.
Can you explain that a bit further? For example, if you had one engine pointing backwards and the other forwards, you wouldn’t expect the ship to go straight.
No. What I’m saying is, one engine is to the right of the centerline, and the other is to the left. Both are rear of the center of mass, and equidistant from the center of mass. They are both thrusting in the same direction. (see figure below)
With the same amount of thrust for each, the ship should move forward and not rotate. Using AddForce, of course, works, because it doesn’t worry about torque. AddForceAtPosition, however, does not work as expected (wished). If I use AddForceAtPosition for each engine, and use each engine’s position as the point at which it’s force should be added, the ship starts off ok, but eventually starts rotating. With equal force applied at both of the engine points, the net torque should be zero. It doesn’t happen this way in practice, though. It starts, what can best be described as, fish-tailing as it goes.
Unfortunately, my desing accounts for failure of engines, meaning, one could fail, at which point the ship actually would start to rotate. As such, AddForce is not a viable solution. Currently, I am having to do the math and apply the torque manually. AddForceAtPosition would be useful, but it doesn’t seem to work right.
Why not just use AddTorque to the direction of a blown engen and keep it simple instead of trying to make a physics based aproche.
Should give you the same effect without a insane about of tweaking to get 2 engens to ballence the push also what happens when you want 4 or 6 engens, 4-6x the tweaking to get it right.
//
If engen left == dead we are thrusting forward
then addtorque left slightly.
//
Then just use AddRelativeForce to the ships Z axis to make it go forward. (cut it in half since one engens dead)
Physics alone can get crazy resaults so try to keep it simple.
This is from the Computer not being able to simulate physics perfectly, there is allways going to be some floating point errors in the physics.
I currently am using AddTorque(). That’s the alternate approach. Pretty much what you described. Each engine calculates it’s force and torque. A propulsion script adds up all of the thrust and all of the torque from all the engines and generates a net thrust and a net torque, which are applied separately. AddForceAtPosition was just preferable b/c it does it all for you. As it is now, I calculate the torque based on engine’s position relative to center of mass and the engine’s thrust. That way, an engine dies, the loss of thrust is factored into the ship’s net thrust and net torque. It works. I was just trying to use AddForceAtPosition to do the math for me.
Is it possible that floating point precision errors account for your problem? Interesting.
How about having a single use of addforceatposition, equal to the thrust of both engines. You could then slide it along the x axis relative to the thrust difference between the two.
Well, I’ve got it working manually calculating torque and adding it myself. I’m wondering if the issue was a result of the limit on angular velocity, but that would only account for the fish-tailing effect I was seeing. It still doesn’t explain why it would start rotating in the first place.
I suspect your solution of a single AddForceAtPosition() at a position of x relative to the ratio of thrust of one to the other might work. Now that I have it working the other way, I am inclined to forge ahead rather then bog myself down experimenting with it. I appreciate everyone’s imput on the subject, and, maybe one day, I will re-visit the issue and see if I can’t figure the problem out.
Are you using primitives at this point? If not I could imagine very small deviations from symmetry could cause the effects you are noticing. Of course there is also rounding and FP errors.
If you rely on a very specific physical behaviours to realise your game you might be better off writing your own physics.
I am using primitives, and, actually, I think small deviations from symmetry are exactly the problem, now that I think of it. I constructed a quick mock-up of a ship using a few cubes, all contained in a parent object representing the ship, which has the rigidbody. It just dawned on me that the center of mass is calculated based on all of the colliders, and I doubt my cubes are symmetrically (precisely)positioned across the Z-axis. That is probably the issue. My engines are offset symmetrically from the z-axis, but the CoM probably doesn’t fall precisely on the z-axis (or other axes, for that matter). I’ll check that when I get home today. I’ll just use a single cube to test it.