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
1
Question by kromenak · May 14, 2013 at 05:26 PM · physicsvelocityforce

Why does using a temporary variable break rigidbody?

So, this is kind of an odd situation; I have two scripts attached to a rigidbody. One script will apply a horizontal force when the player presses a button:

 // Apply a force in a direction.
 rigidbody.AddForce(dir * power, ForceMode.Impulse);

And another has logic for limiting the velocity of the rigidbody:

 Vector3 tempVelocity = rigidbody.velocity;
 if(maxVelocitySq > 0.0f && tempVelocity.sqrMagnitude > maxVelocitySq)
 {
     tempVelocity *= slowdownRate;
 }
 rigidbody.velocity = tempVelocity;

However, when I run the game, the horizontal force doesn't work. I thought that there might be some sort of conflict or overwriting of the rigidbody's velocity force based on the update order of these two scripts, but then I found that I could fix the problem by NOT using a temporary variable in the second script:

 // If velocity is too high, apply a slowdown.
 if(maxVelocitySq > 0.0f && rigidbody.velocity.sqrMagnitude > maxVelocitySq)
 {    
     rigidbody.velocity *= slowdownRate;
 }

And that second version works fine.

My question, then: why would using a temporary variable break the AddForce line in the first script? Does Unity execute physics updates concurrently on different threads, so using a temp variable might overwrite some data? Is there something wrong with using a temp variable? Or is it a bug that rigidbodies would behave this way? I'd note that I'm working on an iOS/Android title, but I only ever see this behavior in the editor.

Comment
Add comment · Show 7
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 zombience · May 14, 2013 at 05:44 PM 0
Share

strange indeed... is it more convenient to have this operating in two separate scripts? have you tried combining this code into one script? i got nothin here, that seems like a bug.

avatar image robertbu · May 14, 2013 at 05:44 PM 0
Share

This is reproducible? That is, if you undo the change the problem reoccurs? And this code is exactly as it is in your project? You havn't 'simplified' anything for the post?

avatar image kromenak · May 14, 2013 at 08:18 PM 0
Share

Yeah, it seems reproducible, currently using 4.1.2f1. When I use a temporary variable, I don't see other forces applying to the object as I'd expect. Swap to not using a temp variable, and it seems fine. If nothing seems out of place, I can submit a bug report and see if Unity can find any issues.

avatar image Adamcbrz · May 14, 2013 at 08:22 PM 0
Share

can we get an entire script that displays the problem. It could be a problem with order of operation.

avatar image kromenak · May 14, 2013 at 08:46 PM 0
Share

Sure; basically, I've got a Dasher class with a public method, Dash, which is called from FixedUpdate in response to an input event (such as a swipe):

 public class Dasher : $$anonymous$$onoBehaviour
 {
     [SerializeField]
     private float power = 100.0f;
 
     public void Dash(Vector2 direction)
     {
         // Apply a force in a direction.
         rigidbody.AddForce(direction.normalized * power, Force$$anonymous$$ode.Impulse);
     }
 }

Then, I have a second script, called PhysicsObject, which does some velocity limiting in FixedUpdate:

 public class PhysicsObject : $$anonymous$$onoBehaviour 
 {
     // $$anonymous$$aximum velocity of physics object.
     [SerializeField]
     private float maxVelocity = 0.0f;
     private float maxVelocitySq = 0.0f;    
     
     // If exceeding max velocity, slow down by this percent.
     [SerializeField]
     private float slowdownRate = 0.9f;
 
     // A maximum velocity for falling.
     [SerializeField]
     private float maxFallVelocity = -8.0f;
 
     private void Awake()
     {
         maxVelocitySq = maxVelocity * maxVelocity;
     }
 
     private void FixedUpdate()
     {
         if(!rigidbody.is$$anonymous$$inematic)
         {            
             Vector3 velocity = rigidbody.velocity;
 
         // If velocity is too high, apply a slowdown.
             if(maxVelocitySq > 0.0f && velocity.sqr$$anonymous$$agnitude > maxVelocitySq)
             {
                   velocity *= slowdownRate;
             }
 
             // Limit the fall velocity.
             if(maxFallVelocity != 0.0f)
             {
                 velocity.z = $$anonymous$$athf.Clamp(velocity.z, maxFallVelocity, $$anonymous$$athf.Infinity);
             }
 
             rigidbody.velocity = velocity;
         }
     } 
 }

In that second script, things work fine if I don't use that temp variable, but I also don't know how I could limit Z velocity like that without using a temp variable. So far, I've only seen this behavior in the editor, and not entirely consistently. It feels like an execution order issue, but I have tried to explicitly order the scripts using $$anonymous$$ono$$anonymous$$anager, but it doesn't seem to make a difference.

Show more comments

1 Reply

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

Answer by kromenak · Jun 11, 2013 at 07:40 PM

So, I never really found an answer to why a temporary variable would cause such unexpected physics issues. However, I suppose a valid solution to temporary variables breaking physics is to not use a temporary variable:

 // Limit the player's fall velocity.
 if(rigidbody.velocity.z < maxFallVelocity)
 {
     float diff = rigidbody.velocity.z - maxFallVelocity;
     Vector3 force = new Vector3(0.0f, 0.0f, -diff);
                     
     rigidbody.AddForce(force, ForceMode.VelocityChange);
 }

This seems to do the trick by calculating an opposing force on the player and applying it using good old "AddForce". Note that the game I'm working on has gravity on the Z-axis (due to nav-mesh limitations), so you'd probably want to change those Zs to Ys if you copy this code.

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

15 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

Related Questions

Move gameobject at constant speed 1 Answer

Calculate velocity to set to reach a target point on a plane considering the drag. 0 Answers

how to get starting velocity of an object, which is thrown with a 45 degree angle and will pass some (x,y) point 0 Answers

Can I, someway, avoid centripetal force? 0 Answers

Move Player Car in Forward Direction using Physics Force 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