Howdy all! Back again, this time I'm experimenting with some Physics as they apply to a Space Ship. So far, I've gotten the bulk of what I wanted to work, well...Working. I have one small hiccup though: First, the Space Ship object instantiates four Thruster Objects. I then do all the math to figure out the amount of torque to be applied to the rigid body center of mass. The idea is that the four (up to a maximum of 6) thrusters each balance each other out, since they're radially symetric (the idea here is that as a thruster is destroyed, maneuvering becomes more and more difficult due to differential thrust). Right now every single thruster seems to be acting through the same point which is the top most thruster of the four. It definitely rotates the ship, but with all four thrusters it should be pushed forward as all the thrusters act on the center of mass of the ship. So the question is: What did I do wrong? Do I need to treat each thruster individually? Or is the current setup sufficient to make things work with some tweaking? Here's my code, and also attached is the project. Any and all help is greatly appreciated! Code (CSharp): using UnityEngine; using System.Collections; [RequireComponent(typeof(Rigidbody))] public class SpaceShip : MonoBehaviour { public Rigidbody spaceShipRB; const int MAX_COMBAT_THRUSTERS = 6; public int numberOfCombatThrusters = 4; private Thruster[] combatThruster = new Thruster[MAX_COMBAT_THRUSTERS]; public Transform[] combatThrusterPosition = new Transform[MAX_COMBAT_THRUSTERS]; public Transform spaceShipCOM; private float[] angle = new float[MAX_COMBAT_THRUSTERS]; private Vector3[] thrusterToCOMDistance = new Vector3[MAX_COMBAT_THRUSTERS]; private float[] spaceShipTorque = new float[MAX_COMBAT_THRUSTERS]; //Calculates the Angle from the Thruster to the COM of the Ship public void CalculateThrusterToCOMAngle(int i) { Vector3 targetDirection = spaceShipCOM.position - combatThrusterPosition[i].position; Vector3 forward = combatThrusterPosition[0].forward; angle[i] = Mathf.Deg2Rad * Vector3.Angle(targetDirection, forward); } //Returns the angle between the Thruster and the COM of the Ship public float GetThrusterToCOMAngle(int i) { return angle[i]; } //Calculates the Distance from the Thruster to the Ship COM public void CalculateThrusterToCOMDistance(int i) { thrusterToCOMDistance[i] = combatThrusterPosition[i].position - spaceShipCOM.position; } //Returns the distance between the Thruster and the COM of the Ship public float GetThrusterToCOMDistance(int i) { return thrusterToCOMDistance[i].magnitude; } //Calculate the Torque applied to the Spaceship COM public void CalculateTorque(int i) { spaceShipTorque[i] = thrusterToCOMDistance[i].magnitude * combatThruster[i].GetThrust() * Mathf.Sin(GetThrusterToCOMAngle(i)); } //Returns the Torque applied to the Spaceship COM public float GetTorque(int i) { return spaceShipTorque[i]; } //Applies the Calculated Torque values of the Thrusters to the RigidBody public void ApplyTorque(int i) { spaceShipRB.centerOfMass = spaceShipCOM.position; spaceShipRB.AddTorque(spaceShipCOM.transform.right * spaceShipTorque[i] * Time.deltaTime); } void Awake() { spaceShipRB = GetComponent<Rigidbody>(); for (int i = 0; i < numberOfCombatThrusters; i++) { combatThruster[i] = (Thruster)Instantiate(Resources.Load("Thruster", typeof(Thruster)), combatThrusterPosition[i].position, Quaternion.identity); CalculateThrusterToCOMAngle(i); CalculateThrusterToCOMDistance(i); CalculateTorque(i); } } void Start() { } void FixedUpdate() { for (int i = 0; i < numberOfCombatThrusters; i++) { ApplyTorque(i); combatThruster[i].transform.position = combatThrusterPosition[i].position; combatThruster[i].transform.rotation = combatThrusterPosition[i].rotation; } } }
Hahah...With as much as I've read the API you'd think I would have caught that. Oh well. I'll plug that in and see what happens.
Hmm...Well, I got the ApplyForceAtPosition working...but there's no torque effect when there's only 1 thruster on the ship. If I have 1 thruster I should get a rotation about the COM in one axis, 2 thrusters is no rotation, 3 would give rotations in 2 axes and 4 would result in no rotation again. So...sort of there with ApplyForceAtPosition
Solved it with this: spaceShipRB.AddForceAtPosition(new Vector3(0,0,spaceShipTorque), combatThrusterPosition.position); Thanks for the assist! V/R Brad
Spoke to soon...So, the behavior works...sort of. The ship starts rotating about the center of mass, and then goes flying off in a crazy direction. Here's an updated package for review. I'm sure it's something small that i'm missing...any help is greatly appreciated! V/R Brad
And solved it. I stripped everything down to the bare essentials. Experimented with some simple Vectors only and voila. Worked like a champ. Going strictly off the API and reading/understanding saved the day here. Thanks for the point in the right direction, this one is solved!