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 EvilTelephone · Aug 01, 2013 at 03:24 AM · physicslimittorqueangularvelocityaddtorque

Restricting angularVelocity on one particular direction


EDIT: I created a video that describes this question and shows the issue. Please watch it here:

https://www.youtube.com/watch?v=sCErZYzg-yU


How could I prevent applying torque in a particular direction if angularVelocity in that direction exceeds a specific 'speed limit', while still applying torque in all other directions that have not exceeded the speed limit?

Problem and what I'm trying to achieve:

I have the player able to control a rigidbody ball through an obstacle course. That part works well. I use addTorque on the ball using a vector based on player input relative to the camera's rotation around the y axis.

The problem is if I set the ball's maximum angular velocity to an arbitrary speed limit, it does prevent a player from exceeding that speed, but the ball no longer rolls down slopes in a believable manner. It hits that max angular velocity and rolls slowly down the slope at that constant velocity.

What I'd like to achieve is, when the ball is on a downward slope, it can accelerate (because of gravity*) to virtually any speed as long as it continues down that slope. The challenge, though, is I need a way to limit how fast the player can cause the ball to spin via input. I haven't figured out a reliable way to do that.

What I've tried so far:

I could just say if the ball's angularVelocity.magnitude > speedLimit, then ignore player input for that update, but that would cause the ball to be completely uncontrollable once it reached a certain speed. I want players to still be able to steer the ball and resist gravity on a downward slope.

I tried using a dot product, comparing the input vector with the current angularVelocity's vector. I scripted that if the two vectors were dissimilar enough, the player's input would be processed. This method proved to be VERY unreliable. The speed would only sometimes be limited to the speedLimit value.

I tried checking the ball's velocity, rather than angulerVelocity. I checked each direction (x, y, z) separately and, if velocity in that direction was higher than the speed limit (or lower than the speed limit * -1), I ignored input on that axis. This was the one that almost worked OK. It limited the speed pretty reliably, but for reasons I couldn't figure out, the player input was ignored at times when it shouldn't have been.

Summary of question:

How can I have a high maximum angular velocity, but prevent users from exceeding a different, lower maximum angular velocity when processing player input and, based on the same player input, apply torque to any directions where the angular velocity speed limit has not been exceeded even if some directions have exceeded this speed limit?

Thank you.

Comment
Add comment · Show 3
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 robertbu · Aug 01, 2013 at 05:22 AM 0
Share

This problem is very hard to visualize for me. I kinda get it, but not well enough to offer a fix. It sounds to me like you would want to fix the angular velocity to some multiple of the velocity and the axis of rotation to be the cross product of the Vector3.up and the velocity vector.

$$anonymous$$aybe you could put your app on a web page, or take a video and put it on YouTube so we can visualize the problem.

avatar image EvilTelephone · Aug 01, 2013 at 01:47 PM 0
Share

robertbu, I'll see what I can do. $$anonymous$$aybe I'll make a video. It would probably be the easiest way to show what I'm trying to achieve. Thanks.

avatar image EvilTelephone · Aug 02, 2013 at 04:43 AM 0
Share

robertbu, I have created a video. Please check it out here: https://www.youtube.com/watch?v=sCErZYzg-yU. Thank you!

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Owen-Reynolds · Aug 01, 2013 at 12:36 PM

Most problems like this can be solved by using a local coordinate system. Find the current "forward"; get copies with everything spun by those numbers; check/adjust things using x=sideways, z=forward; then spin everything back to get real final values.

Suppose you know the current slope is facing slopeDir. Find the y-spins to covert to and from local coords:

 // find the spin around y to convert to/from local coords:
 Vector3 flatDir = slopeDir; flatDir.y=0;
 Quaternion toLocal = Quaternion.FromToRotation(flatFwd, Vector.forward);
 // NOTE: this will (almost) always be a y-rotation
 Quaternion fromLocal = Quaternion.FromToRotation(V3.forward, flatFwd);

 // get local everything:
 Vector3 localVel = toLocal * rigidbody.velocity;
 Vector3 localAngV = toLocal * rigidbody.angularVelocity;

Now it's like the ball is always moving due north, so easier to work with the numbers. It happens that angularVelocity is in radians (angVel.x=6.28 will make 1 spin/second.)

 if(localAngV.z>45*Mathf.Deg2Rad) // ball is spinning quickly right
 if(localVel.x<1) // moving left on the slope ...
 if(localAngV.x<0) // ball is spinning backwards!!

Once you've adjusted everything, convert back to the real numbers:

 rigidbody.velocity = fromLocal * localVel;
 rigidbody.angVel = fromLocal * localangV;

One problem is if the ball is facing exactly backwards, Quat.FTrot will sometimes decide not to give a y-rotation. Instead it will spin over the top (or under the bottom.) Can check for that specially.

transform.TransformDirection (and InverseTD) do the same thing as the first step -- convert to and from local coords. But they would use the ball's forward arrow (which is random for a spinning ball,) and include any up/down tilt.

Comment
Add comment · Show 2 · 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 EvilTelephone · Aug 01, 2013 at 01:55 PM 0
Share

Oh, that's very interesting. So, after the calculations at the top, it's as if the ball is always sitting on a flat surface for the rest of the calculations, right?

One issue I would have is figuring out the slope at every update. Is there a command, or commands, in Unity that could tell me the slope of wherever the ball is currently at assu$$anonymous$$g it's in contact with the 'ground'? Consider a hilly environment. The slope would be constantly changing.

I realize a single point doesn't really have a slope, so to calculate that, would it have to take in to consideration the current vector of the object in the world?

EDIT: Now that I'm thinking this over, the ball's current vector (relative to the world) sort of is the slope, right? Could I get the 'slopeDir' from that at each update?

avatar image Owen-Reynolds · Aug 01, 2013 at 02:56 PM 0
Share

If you use the "slope arrow" as the local forward, yes it's like the ball is on a flat surface facing North. I used the direction only (not the slope's +/-Y) to get just "like it's facing north."

People often use the current velocity (flattened with y=0 or not) as a ball's current forward. But, in your case, it seems your game has to "know" which way is forward along the path you've made. $$anonymous$$aybe by marking with empty (faced "path forward") transforms, or some some of spline.

For slopes, you can raycast down and grab the normal. Setting y=0 gives the direction of the downward slope.

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

16 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

Related Questions

Using Torque to kill Angular Velocity 2 Answers

AddTorque application is too slow 1 Answer

Do I understand Time.deltaTime? 2 Answers

AddTorque does not use ForceMode as expected (Different than AddForce) 1 Answer

Restrict additional torque force to max rotation velocity 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