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 T27M · Dec 20, 2013 at 08:26 PM · c#velocitychangeridgidbody

Calculate a wanted velocity/direction?

Say I have a GameObject with a ridgidbody that is motionless. Given a direction and a force I use addforce() to accelerate the object in that direction. When the GameObject reaches a max velocity the force is no longer applied and the GameObject drifts along its path.

Now say I want to change direction, currently I'm using the ridgidbody's drag setting to counteract the inertia. This works fine, but the problem is how do I determine when the GameObject is traveling in the new direction. I want the drag to be 0 when the GameObject is traveling in the correct direction so that I don't have to apply force to keep the object up to speed and the drag to only be applied while the GameObject is changing direction.

Hope i made that clear enough to understand, Thanks.

Update:

This is called in FixedUpdate()

wantedDirection is a raycast direction from the mouse when no object or destination vector is given.

             direction = Vector3.MoveTowards(direction, wantedDirection, turnSpeed * Time.deltaTime);
             targetRotation = Quaternion.LookRotation(direction);
             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
 
             if (Vector3.Angle(direction, rigidbody.velocity) < 0.01f) 
                 rigidbody.drag = 1.0f;
             else
                 rigidbody.drag = 0.0f;
             
             if(currentSpeed < currentTopSpeed ){
                 rigidbody.AddForce(direction * acceleration, ForceMode.Acceleration);
             }
Comment
Add comment · Show 9
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 · Dec 20, 2013 at 09:26 PM 0
Share

Looks to me like you want to use 'wantedDirection' ins$$anonymous$$d of 'direction' on line 5. Depending on your goals, that may also be true on line 11. In fact, this code is a bit like the cart dragging the horse. I'd probably do it this way:

 if (Vector3.Angle(wantedDirection, rigidbody.velocity) > 0.01f) 
     rigidbody.drag = 1.0f;
 else
     rigidbody.drag = 0.0f;
     
 if (currentSpeed < currentTopSpeed) {
         rigidbody.AddForce(wantedDirection * acceleration, Force$$anonymous$$ode.Acceleration);
     }
     
 transform.rotation = Quaternion.LookRotation(rigidbody.velocity);

You'll have to adjust 'drag' as appropriate to your situation. And I had the comparison or the 'if' backwards in the original answer.

avatar image T27M · Dec 20, 2013 at 09:36 PM 0
Share

I had the slerp for the rotation because the ship was "snaping" to the new direction rather than gradually rotating around.

The code sort of works, but once the top speed is reached the force is no longer applied and the drag always remains at 0 after the first click, so there is no drag to slow the ship down to then apply the force in the correct direction.

avatar image T27M · Dec 20, 2013 at 09:43 PM 0
Share

Actually the drag flickers between 0 and 1 after I first set the direction and then once the direction is changed again it stays at 0.

avatar image robertbu · Dec 20, 2013 at 09:52 PM 0
Share

$$anonymous$$y code suggestion won't make it snap. The rotation follows the ship rather than the force following the rotation. If it is rotating too fast then lower the drag.

You need to debug the flicker. Start by outputting the Angle calculated each frame.

 float angle = Vector3.Angle(wantedDirection, rigidbody.velocity);
 Debug.Log(angle);

I would assume resetting drag frequently would work, but as an alternate, you could set Drag to 0.0, and do:

 if (Vector3.Angle(wantedDirection, rigidbody.velocity) > 0.01f) 
     rigidbody.velocity *= 0.99;

Adjust the '0.99' as appropriate, but it needs to be near but less than 1.0.

avatar image robertbu · Dec 20, 2013 at 10:14 PM 1
Share

The same angle calculation can work for both:

 bool turning = Vector3.Angle(wantedDirection, rigidbody.velocity) > 0.01f;

then:

 if (turning) 
     rigidbody.drag = 1.0f;
 else
     rigidbody.drag = 0.0f;

and:

 if (currentSpeed < currentTopSpeed || turning) {
         rigidbody.AddForce(wantedDirection * acceleration, Force$$anonymous$$ode.Acceleration);
     }

The only problem I can see is that you can come out of the turn with a higher velocity than your 'currentTopSpeed'. One solution would be to modify the drag clause:

 if (turning || currentSpeed > currentTopSpeed) 
     rigidbody.drag = 1.0f;
 else
     rigidbody.drag = 0.0f; 

That way the drag would stay on until the speed was again below 'currentTopSpeed'.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by robertbu · Dec 20, 2013 at 08:59 PM

You can use either Vector3.Angle() or Vector3.Dot() to determine if the ship is going in the same direction as the force is being applied.

 if (Vector3.Angle(forceDirection, rigidbody.veloicty) > 0.01f) 
     rigidbody.drag = 2.0f;
 else
     rigibody.drag = 0.0f;


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 T27M · Dec 20, 2013 at 09:18 PM 0
Share

I tried this code; the first time I set a destination the drag set correctly, after that it remained at 0. I updated my question with some code.

avatar image robertbu · Dec 20, 2013 at 09:34 PM 0
Share

I just posted more info as a comment to your question. The primary issue was that the 'if' comparison was backwards. Fixed now.

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

18 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

How do I use addforce relative to a parent's rotation 0 Answers

Gradually slow down motion while jumping? 0 Answers

How to adjust the speed of an object? 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