Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 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 CoolCasualCat · Jan 21, 2016 at 06:26 PM · c#rigidbody2dphysics2dtorqueaddtorque

Rotate a 2D Rigidbody to a desired angle using AddTorque?

In my game I have several rigidbodies that interact with eachother using physics. The objects will be rotating, but I can't get the objects to rotate to any desired angle because the angles just don't seem to be reliable for any calculations (to my level of knowledge).

Is there anyway I could make a 2d PID controller so then the rigidbody will rotate properly to a given angle.

Or could I at least get some help on making calculations with angles.

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

3 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by MelvMay · Jan 22, 2016 at 01:26 PM

I think the best way I can help you is to describe how, when applying a single torque value, it is used during the next fixed-update.

When you call Rigidbody2D.AddTorque, the value you use is added to an internal torque value and is only used (and subsequently reset back to zero) during the fixed-update.

During the fixed-update, this accumulated torque value (or only a single one if you only called AddTorque once) will be added to the Rigidbody2D.angularVelocity using the formula:

Rigidbody2D.angularVelocity += Time.fixedTimeDelta x (1 / Rigidbody2D.inertia) x Torque

It's worth pointing out that the angular velocity of a body will stay at this value unless a force acts on the body to change it and/or Rigidbody2D.angularDrag is used so it should be set to zero if you don't require such drag.

The angular velocity changes the Rigidbody2D.rotation using the formula:

Rigidbody2D.rotation += Time.fixedTimeDelta x Rigidbody2D.angularVelocity

In simpler terms; the torque value is what modifies the angular velocity of the body by being multiplied by the time-step and the inverse body rotational inertia. This angular velocity changes the body rotation by being multiplied simply by the time-step.

Alternately, if you don't want to use forces and directly manipulate the Rigidbody2D.angularVelocity then everything becomes much simpler. Simply setting the angular velocity means setting a value in degrees/second the object will rotate. If you calculate how many degrees (positive or negative) you need to move then simply set the angular velocity and wait for the appropriate amount of time. This methods makes it easy to set an angular speed (it's the angular velocity itself).

Another way is to use Rigidbody.MoveRotation. After you've calculated how many degrees you need to move (as above) then simply call the above method during fixed-update by linearly interpolating (Mathf.Lerp) from the starting angle to the target angle.

Comment
Add comment · Show 1 · Share
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
avatar image CoolCasualCat · Jan 22, 2016 at 08:59 PM 0
Share

wait so the angular velocity will be dependant on the torque? shouldn't it be the other way around? like the torque should be proportional to the difference between the target and current angular velocity, and the target angular velocity will be proportional to the difference in the target and current angle of the rigidbody?

Sorry if I totally missed something obvious. I'm trying to understand all this at 2A$$anonymous$$

avatar image
1

Answer by manesh · Mar 31, 2016 at 03:34 AM

Here's my quick and dirty solution, after being flummoxed trying to figure this out. Using Unity 5.4b12.

The most important thing I figured out is rotation is in degrees. It can go above 360 (e.g. 720, 1080, etc.) as well as be negative (-360, -720, etc.), depending on how the object was rotated. Some simple math makes it consistent.

 float angle = this.rigidbody2d.rotation % 360;
 float torque = 0.25f;
 if(angle < 0)
     angle += 360;
 
 if(angle < 1f || angle > 359f)
 {
     this.rigidbody2d.transform.rotation = Quaternion.identity;
 }
 else if(angle > 180f)
 {
     this.rigidbody2d.AddTorque(torque);
 }
 else
 {
     this.rigidbody2d.AddTorque(-torque);
 }
Comment
Add comment · Share
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
avatar image
0

Answer by felres · Jan 25 at 09:46 PM

For anyone that happens to stumble upon this thread Ive made this method that makes a 2d rigidbody rotate to face a specific angle, using only AddTorque.

Heres an example of how I use it in code:

 private void FixedUpdate()
     {
         float horizontalMove = horizontalInput * (isUnderwater ? underwaterSpeedX : inlandSpeed);
         float verticalMove = verticalInput * (isUnderwater ? underwaterSpeedY : 0f);
         forceToAdd = new Vector2(horizontalMove, verticalMove);
 
         GameManager.TorqueTo(transform.right, forceToAdd, rb, maxTorque, torqueDampFactor);
     }

The actual code:

     /// <summary>
     /// Use AddTorque() to face a specific angle. For 2D physiscs. Should be called in every FixedUpdate() frame.
     /// </summary>
     /// <param name="currentVec"> vector representing the direction we are currently pointing at. (transform.right) </param>
     /// <param name="targetVec"> vector representing the direction we want to point at. </param>
     /// <param name="rb"> Rigidbody to affect. </param>
     /// <param name="maxTorque"> Max torque to apply. </param>
     /// <param name="torqueDampFactor"> Damping factor to avoid undershooting. </param>
     /// <param name="offsetForgive"> Stop applying force when the angles are within this threshold (default 0). </param>
     public static void TorqueTo(Vector3 currentVec, Vector3 targetVec, Rigidbody2D rb, float maxTorque, float torqueDampFactor, float offsetForgive = 0)
     {
         float targetAngle = FindAngle(targetVec);
         float currentAngle = FindAngle(currentVec);
         float angleDifference = AngleDifference(targetAngle, currentAngle);
         if (Mathf.Abs(angleDifference) < offsetForgive) return;
 
         float torqueToApply = maxTorque * angleDifference / 180f;
         torqueToApply -= rb.angularVelocity * torqueDampFactor;
         rb.AddTorque(torqueToApply, ForceMode2D.Force);
     }

This method does use other "helper" methods, to make my life easier in general. They should be pasted under the main method above. I personally put them all on a global "helper" script to use them everywhere (this is possible by making them static). Here they are:

     /// <summary>
     /// Returns the angle (in degrees) in which the vector is pointing.
     /// </summary>
     /// <returns>0-360 angle </returns>
     public static float FindAngle(Vector2 vec)
     {
         return FindAngle(vec.x, vec.y);
     }
     public static float FindAngle(float x, float y)
     {
         float value = (float)((System.Math.Atan2(y, x) / System.Math.PI) * 180);
         if (value < 0) value += 360f;
         return value;
     }


     public static float AngleDifference(float a, float b)
     {
         return ((((a - b) % 360f) + 540f) % 360f) - 180f;
     }



Comment
Add comment · Share
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

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

62 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Torque stopped working after update 1 Answer

More realistic physics on child collisions 2D 0 Answers

Is it ok to use Linear Drag and/or Mass to make an object immovable? 2 Answers

How to disable collisions without disabling rigidbody? 1 Answer

Multiple Cars not working 1 Answer


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