- Home /
Find turning radius with torque
I have a 3d space game where all ships move around using physics. I am trying to determine if a given object is reachable by a ship at a given velocity and turn radius. I believe the formula for turn radius movementSpeed / rotation_in_radians but that doesn't seem to be working for me. I think it is because the torque rotations are unpredictable and changing rotations takes extra time because of excess torque in a different direction. There is also a bit of a slip factor in AerodyanmicEffect that probably needs to be accounted for.
I have code to tell if something is within a given turn radius that I am pretty sure works
 public bool InsideTurnRadius(Vector3 point) {
     float turnRadius = GetTurnRadius();
     var toTarget = point - transform.position;
     toTarget = Vector3.ProjectOnPlane(toTarget, transform.forward);
     var toCenterNormalized = toTarget.normalized;
     var turnRadiusCenter = transform.position + toCenterNormalized * turnRadius;
 
     return ((point - turnRadiusCenter).sqrMagnitude) > (turnRadius * turnRadius);
 }
But I don't know how to actually find the right turn radius value to plug in there.
Does anybody know how I can account for all the forces to determine if a target point is reachable?
I am using a cut down and modified version of the Unity Standard Assets Plane script.
 public class SpaceCraftController : MonoBehaviour {
 [SerializeField]
 private float m_MaxEnginePower = 40f;        // The maximum output of the engine.
 [SerializeField]
 private float m_AerodynamicEffect = 0.5f;   // How much aerodynamics affect the speed of the aeroplane.
 [SerializeField]
 private float m_ThrottleChangeSpeed = 0.3f;  // The speed with which the throttle changes.
 
 public float Throttle { get; private set; }                     // The amount of throttle being used.
 public float ForwardSpeed { get; private set; }                 // How fast the aeroplane is traveling in it's forward direction.
 public float EnginePower { get; private set; }                  // How much power the engine is being given.
 public float MaxEnginePower { get { return m_MaxEnginePower; } }    // The maximum output of the engine.
 public float RollAngle { get; private set; }
 public float PitchAngle { get; private set; }
 public float RollInput { get; private set; }
 public float PitchInput { get; private set; }
 public float YawInput { get; private set; }
 public float ThrottleInput { get; private set; }
 
 public float maxPitchSpeed = 360;
 public float maxRollSpeed = 360;
 public float maxYawSpeed = 360;
 public bool useAeroFactor = true;
 
 private float m_AeroFactor;
 private Rigidbody m_Rigidbody;
 
 [Header("Debug")]
 public bool drawVelocity = true;
 
 
 
 
 /* THIS IS WHAT I NEED A HAND WITH */
 public float TurnRadius {
     get {
         float pitchRadius = maxPitchSpeed * Mathf.Deg2Rad;
         float yawRadius = maxYawSpeed * Mathf.Deg2Rad;
         if (pitchRadius > yawRadius) {
             return ForwardSpeed / (yawRadius);
         } else {
             return ForwardSpeed / (pitchRadius);
         }
     }
 }
 
 private void Start() {
     m_Rigidbody = GetComponent<Rigidbody>();
 }
 
 public void Move(float rollInput, float pitchInput, float yawInput, float throttleInput) {
     RollInput = rollInput;
     PitchInput = pitchInput;
     YawInput = yawInput;
     ThrottleInput = throttleInput;
 
     ClampInputs();
 
     CalculateRollAndPitchAngles();
 
     ControlThrottle();
 
     CaluclateAerodynamicEffect();
 
     CalculateTorque();
 
     if (drawVelocity) {
         Debug.DrawRay(transform.position, GetComponent<Rigidbody>().velocity.normalized * ForwardSpeed, Color.white);
     }
 }
 
 private void ClampInputs() {
     RollInput = Mathf.Clamp(RollInput, -1, 1);
     PitchInput = Mathf.Clamp(PitchInput, -1, 1);
     YawInput = Mathf.Clamp(YawInput, -1, 1);
     ThrottleInput = Mathf.Clamp(ThrottleInput, -1, 1);
 }
 
 /* ALSO not 100% sure why this works, if anybody knows I'd be very happy to learn*/
 private void CalculateRollAndPitchAngles() {
     // Calculate roll & pitch angles
     // Calculate the flat forward direction (with no y component).
     var flatForward = transform.forward;
     flatForward.y = 0;
     if (flatForward.sqrMagnitude > 0) {
         flatForward.Normalize();
         // calculate current pitch angle
         var localFlatForward = transform.InverseTransformDirection(flatForward);
         PitchAngle = Mathf.Atan2(localFlatForward.y, localFlatForward.z);
         // calculate current roll angle
         var flatRight = Vector3.Cross(Vector3.up, flatForward);
         var localFlatRight = transform.InverseTransformDirection(flatRight);
         RollAngle = Mathf.Atan2(localFlatRight.y, localFlatRight.x);
     }
 
 }
 
 private void ControlThrottle() {
     Throttle = Mathf.Clamp01(Throttle + ThrottleInput * Time.deltaTime * m_ThrottleChangeSpeed);
     EnginePower = Throttle * m_MaxEnginePower;
     m_Rigidbody.AddForce(EnginePower * transform.forward, ForceMode.Acceleration);
     var velocity = m_Rigidbody.velocity;
     var magnitude = velocity.magnitude;
     if (magnitude > 0 && magnitude > m_MaxEnginePower) {
         velocity *= (m_MaxEnginePower / magnitude);
         m_Rigidbody.velocity = velocity;
     }
     // Forward speed is the speed in the forward direction (not the same as its velocity)
     var localVelocity = transform.InverseTransformDirection(m_Rigidbody.velocity);
     ForwardSpeed = Mathf.Max(0, localVelocity.z);
 }
 
 private void CaluclateAerodynamicEffect() {
     // "Aerodynamic" calculations. This is a very simple approximation of the effect that a plane
     // will naturally try to align itself in the direction that it's facing when moving at speed.
     // Without this, the plane would behave a bit like the asteroids spaceship!
     if (m_Rigidbody.velocity.sqrMagnitude > 0) {
         // compare the direction we're pointing with the direction we're moving
         //areoFactor is between 1 and -1
         m_AeroFactor = Vector3.Dot(transform.forward, m_Rigidbody.velocity.normalized);
         // multipled by itself results in a desirable rolloff curve of the effect
         m_AeroFactor *= m_AeroFactor;
         // Finally we calculate a new velocity by bending the current velocity direction towards
         // the the direction the plane is facing, by an amount based on this aeroFactor
         var newVelocity = Vector3.Lerp(m_Rigidbody.velocity, transform.forward * ForwardSpeed,
                                        m_AeroFactor * ForwardSpeed *
                                        m_AerodynamicEffect * Time.deltaTime);
         m_Rigidbody.velocity = newVelocity;
 
         // also rotate the plane towards the direction of movement
         m_Rigidbody.rotation = Quaternion.Slerp(m_Rigidbody.rotation,
                                               Quaternion.LookRotation(m_Rigidbody.velocity, transform.up),
                                               m_AerodynamicEffect * Time.deltaTime);
     }
 }
 
 private void CalculateTorque() {
     var torque = Vector3.zero;
     torque += PitchInput * (maxPitchSpeed * Time.deltaTime) * transform.right;
     torque += YawInput * (maxYawSpeed * Time.deltaTime) * transform.up;
     torque += -RollInput * (maxRollSpeed * Time.deltaTime) * transform.forward;
     if (useAeroFactor) {
         m_Rigidbody.AddTorque(torque * m_AeroFactor, ForceMode.Acceleration);
     } else {
         m_Rigidbody.AddTorque(torque, ForceMode.Acceleration);
     }
 }
Your answer
 
 
             Follow this Question
Related Questions
AI Player Jerky Movement - Overcoming Obstacle 0 Answers
Thief Car AI for 3D Game 0 Answers
AI Turret Aiming 2 Answers
AI Aircraft/Spacecraft yaw and pitch help 1 Answer
Kill Rotation of object using forces 0 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                