Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by weix · Apr 28, 2015 at 06:44 AM · physicsaispaceai problems

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);
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges