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 DamDamDuSixZero · Jan 07, 2015 at 09:25 PM · bugvelocity

[bug] Velocity set to 0 by Unity

Hi,

I have a curious bug in my project.

My project is simple, I have a rigidbody who run indefinitly. I ve made a player controller attached to my rigidbody with the following update :

A fixed update to move my rigidbody and flip it if necessary :

     void FixedUpdate () {    
 
         if (grounded) 
         {
 
             rigidbody2D.velocity = new Vector3(xSpeed * direction, rigidbody2D.velocity.y, 0f);
 
 
         }
 
         //flip sprite player
         Vector3 theScale = transform.localScale;
         theScale.x = direction;
         transform.localScale = theScale;
 
 
         leftGroundCheckTransform.position = new Vector2 (collider2D.bounds.min.x+0.05f, collider2D.bounds.min.y-0.05f);
         rightGroundCheckTransform.position = new Vector2 (collider2D.bounds.max.x-0.05f, collider2D.bounds.min.y-0.05f);
         leftSideCheckTransform.position = new Vector2 (collider2D.bounds.min.x - 0.02f, collider2D.bounds.center.y);
         rightSideCheckTransform.position = new Vector2 (collider2D.bounds.max.x + 0.02f, collider2D.bounds.center.y);
 
     }
 

And an Update that make the following thing :

     void Update(){
 
         //check player position
         UpdateGroundedStatus();
 
         
         //check jump
         GestionPlayerJump ();
 
 
         //check speed
         GestionXSpeed ();
 
 
     }


So my problem is :

Everything works fine, but randomly my rigidbody.velocity is set to 0 after an update with no reasons. I've test it Many many time, when the bug comes out, the velocity is set to the right value as the update finish, but when it enter the update again the velocity is set to 0.

It's totally random. I have just a rigibody who run along the scene and run back when there's an obstacle.

I read that Unity sometime bugs when addforce is used at the same time we directly change the velocity, so I deleted all the reference to addforce. But the bug stays here.

I want to know if someone have an idea if it is really a bug or if i make something wrong ? Thanks in advance.

PS sorry for my bad english ! :)

Comment
Add comment · Show 2
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 _dns_ · Jan 07, 2015 at 10:45 PM 0
Share

Hi, it's difficult to spot he problem. I guess you've checked that you never set the velocity to zero with your code (i.e. xSpeed = 0 or direction = 0 before you compute it).

Could it be because sometimes there are 2 Update() called before a FixedUpdate() is called (if the game runs faster than the FixedUpdate rate) or the other way around: 2 FixedUpdate can be called before an Update() is called when the framerate is low. I mean, I don't know what you do in the code called in the Update, just don't assume that there is 1 call to FixedUpdate followed by 1 call to Update, this is not always the case.

avatar image tanoshimi · Jan 07, 2015 at 10:50 PM 0
Share

_dns is right, but it;s impossible to help more without seeing the contents of your
UpdateGroundedStatus();, GestionPlayerJump (); GestionXSpeed (); routines.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by DamDamDuSixZero · Jan 07, 2015 at 11:51 PM

Hi and Thx for your answer.

In fact, I never set the velocity to zero in my code. Sometimes xSpeed is reduced but never set to 0. The same goes for direction.

It's very curious as the rigidbody travels a little space and it can stop the movement after 10sec or after 5mn, it's totaly random. And the position of my rigidbody is never the same when the bug occurs.

I didnt post all my code because I didnt want to make a huge post but i'm going to post it here :

 sing UnityEngine;
 using System.Collections;
 
 public class MuleController : MonoBehaviour {
 
     public float xSpeed = 0.0f;
     public int direction = -1;
     public float xSpeedMax  = 100.0f;
     public float xSpeedMin = 40.0f;
     public float xSpeedAcceleration = 0.008f;
     public float xSpeedDecceleration = 0.05f;
     //le step d acceleration lors du premier appui sur l acceleration
     public float xSpeedAccelerationStep1 = 7.0f;
 
 
     public float jumpForce = 500.0f;
     
     private Transform leftGroundCheckTransform;
     private Transform rightGroundCheckTransform;
     private Transform leftSideCheckTransform;
     private Transform rightSideCheckTransform;
 
     
     private bool grounded;    
     private bool rebond;
     private bool doubleJump;
     private bool rouleboule;
     
 
     private bool rightCol ;
     private bool leftCol ;
     private bool bottomLeftCol ;
     private bool bottomRightCol ;
 
     public int coinsCollected = 0;
     
     public LayerMask groundCheckLayerMask;
     public LayerMask wallCheckLayerMask;
 
 
     // Use this for initialization
     void Start () {
 
 
 
 
         //On associe les checks de la hitbox du player
         leftGroundCheckTransform = transform.Find ("leftGroundCheck");
         rightGroundCheckTransform= transform.Find ("rightGroundCheck");
         leftSideCheckTransform = transform.Find ("leftSideCheck");
         rightSideCheckTransform = transform.Find ("rightSideCheck");
 
 
         //On place les checks à la bonne position
         leftGroundCheckTransform.position = new Vector2 (collider2D.bounds.min.x+0.05f, collider2D.bounds.min.y-0.05f);
         rightGroundCheckTransform.position = new Vector2 (collider2D.bounds.max.x-0.05f, collider2D.bounds.min.y-0.05f);
         leftSideCheckTransform.position = new Vector2 (collider2D.bounds.min.x - 0.02f, collider2D.bounds.center.y);
         rightSideCheckTransform.position = new Vector2 (collider2D.bounds.max.x + 0.02f, collider2D.bounds.center.y);
 
 
     }
     
     // Update is called once per frame
     void FixedUpdate () {
 
 
 
         //gestion du deplacement
         if (grounded || rebond) 
         {
 
             rigidbody2D.velocity = new Vector3(xSpeed * direction, rigidbody2D.velocity.y, 0f);
 
             //on desactive le rebond
             rebond = false;    
 
         }
 
         //flip sprite player
         Vector3 theScale = transform.localScale;
         theScale.x = direction;
         transform.localScale = theScale;
 //        //flip les collid check
         leftGroundCheckTransform.position = new Vector2 (collider2D.bounds.min.x+0.05f, collider2D.bounds.min.y-0.05f);
         rightGroundCheckTransform.position = new Vector2 (collider2D.bounds.max.x-0.05f, collider2D.bounds.min.y-0.05f);
         leftSideCheckTransform.position = new Vector2 (collider2D.bounds.min.x - 0.02f, collider2D.bounds.center.y);
         rightSideCheckTransform.position = new Vector2 (collider2D.bounds.max.x + 0.02f, collider2D.bounds.center.y);
 
     }
 
 
     //update utilisé quand il y a un input button
     void Update(){
 
         //on verifie si le player est au sol
         UpdateGroundedStatus();
 
         
         //gestion du saut
         GestionPlayerJump ();
 
 
         //delimitation de la vitesse
         GestionXSpeed ();
 
 
     }
     
 
     void GestionXSpeed(){
 
         bool startAcceleration = Input.GetButtonDown ("Fire1");
         bool acceleration = Input.GetButton ("Fire1");
         bool stopAcceleration = Input.GetButtonUp ("Fire1");
 
 
         
         //On ne peut accelerer et decellerrer que lors d un rebond ou au sol
         if (grounded || rebond) 
         {
             if (startAcceleration){
                 if (xSpeed < xSpeedAccelerationStep1) xSpeed = xSpeedAccelerationStep1;
             }
             else if (stopAcceleration){
                 xSpeed -= xSpeedDecceleration * 10.0f;
             }
             else {
 
                 if (acceleration && xSpeed <= xSpeedMax)
                     xSpeed += xSpeedAcceleration;
                 if (!acceleration && xSpeed >= xSpeedMin)
                     xSpeed -= xSpeedDecceleration;
             }
         }
 
         //regulation de la vitesse min et max
         xSpeed = Mathf.Clamp (xSpeed, xSpeedMin, xSpeedMax);    
     }
 
     
     void OnCollisionEnter2D(Collision2D collisionInfo){
 
         //debug
         Debug.Log("Points colliding: " + collisionInfo.contacts.Length);
         Debug.Log("First point that collided: " + collisionInfo.contacts[0].point);
         Debug.Log("second point that collided: " + collisionInfo.contacts[1].point);
 
 
         //ON VERIFIE LES COLLISIONS DE CHAQUE COTE 
         rightCol = Physics2D.Linecast (transform.position, rightSideCheckTransform.position, wallCheckLayerMask);
         leftCol = Physics2D.Linecast (transform.position, leftSideCheckTransform.position, wallCheckLayerMask); 
         bottomLeftCol = Physics2D.Linecast (transform.position, leftGroundCheckTransform.position, groundCheckLayerMask);
         bottomRightCol = Physics2D.Linecast (transform.position, rightGroundCheckTransform.position, groundCheckLayerMask);
 
 
         if (rightCol) 
         {
             if (grounded) 
             {
                 direction = -direction;
                 xSpeed -= xSpeed/3;
             }
             Debug.Log ("Col right");
         }
         if (leftCol) 
         {
             if (grounded) 
             {
                 direction = -direction;
                 xSpeed -= xSpeed/3;
             }
             Debug.Log ("Col left");
         }
         if (bottomLeftCol || bottomRightCol) 
         {
             //on verifie si il y a collision sur les coté 
             //au moment du retour au sol
         
             if (rightCol) {direction = -1; xSpeed = xSpeed/2;}
             else if (leftCol) {direction = 1; xSpeed = xSpeed/2;}
             //si au retour sur le sol et face à un mur
             //on perd la moitié de sa vitesse
 
             grounded = true;
 
             //marchepasgrounded = true;
             Debug.Log ("Col bottom");
         }
 
     }//fonction
 
 
     void OnTriggerEnter2D (Collider2D col){
 
 
             if (col.gameObject.CompareTag ("Coins")) {
                         coinsCollected += 1;
                         Destroy (col.gameObject);
                 }
 
         }
 
 
     void GestionPlayerJump(){
 
         bool jump = Input.GetButtonDown ("Fire2");
 
         //if jump
         if (jump) {
             //on check les collisions
             rightCol = Physics2D.Linecast (transform.position, rightSideCheckTransform.position, wallCheckLayerMask);
             leftCol = Physics2D.Linecast (transform.position, leftSideCheckTransform.position, wallCheckLayerMask); 
             bottomLeftCol = Physics2D.Linecast (transform.position, leftGroundCheckTransform.position, groundCheckLayerMask);
             bottomRightCol = Physics2D.Linecast (transform.position, rightGroundCheckTransform.position, groundCheckLayerMask);
 
             //if grounded= jump normal
             if (grounded){
                 //rigidbody2D.AddForce (new Vector2 (0f, jumpForce));
                 //rigidbody2D.velocity+=(new Vector2 (0f, jumpForce));
                 Debug.Log("Jump");
             }
 
             //else if !grounded 
             else {
                 //si il y a une collision a ce moment c un rebond
                 if (rightCol || leftCol) {
                     rebond = true;
                     //on reinitialise le double jump
                     doubleJump = false;
                     //on midifie la direction
                     if (rightCol) direction = -1; 
                     else if (leftCol) direction = 1;
                     //on reiinitialise la force du saut
                     Vector2 newVelocity = rigidbody2D.velocity;
                     newVelocity.y = 0f;
                     rigidbody2D.velocity = newVelocity;
                     //rigidbody2D.AddForce (new Vector2 (0f, jumpForce));
 
                     Debug.Log("Jump");
                 }//si collision
                 //sinon c un double jump
                 else if (!doubleJump){
                     //on reiinitialise la force du saut
                     Vector2 newVelocity = rigidbody2D.velocity;
                     newVelocity.y = 0f;
                     rigidbody2D.velocity = newVelocity;
                     //rigidbody2D.AddForce (new Vector2 (0f, jumpForce));
 
                     Debug.Log("DoubleJump");
                     //le double jump est en cours, il repassera false uniquement en 
                     //cas de contact avec le sol ou lors d un rebond
                     doubleJump = true;
 
 
                 }
             }
         }
     }//fonction
 
 
 
     void UpdateGroundedStatus()
     {
         // The player is grounded if a linecast to the groundcheck position hits anything on the ground layer.
         //grounded = Physics2D.Linecast(transform.position, groundCheckTransform.position, 1 << LayerMask.NameToLayer("Ground"));  
         //grounded = Physics2D.Linecast(transform.position, groundCheckTransform.position, wallCheckLayerMask);  
 
 
         bool bottomLeftCol = Physics2D.Linecast (transform.position, leftGroundCheckTransform.position, groundCheckLayerMask);
         bool bottomRightCol = Physics2D.Linecast (transform.position, rightGroundCheckTransform.position, groundCheckLayerMask);
         grounded = bottomLeftCol;
         if (!grounded)   grounded = bottomRightCol;
         //on reinitialise le double jump
         if (grounded)doubleJump = false;
     }
 

Dont laugh on my code i'm not a pro developper ;)

Comment
Add comment · Show 6 · 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 tanoshimi · Jan 07, 2015 at 11:52 PM 0
Share

And what are the values of xSpeed$$anonymous$$in, xSpeed$$anonymous$$ax set in the inspector?

avatar image DamDamDuSixZero · Jan 07, 2015 at 11:55 PM 0
Share

xSpeed$$anonymous$$in = 5.0f; xSpeed$$anonymous$$ax = 10.0f;

Thx for looking at my problem :)

avatar image _dns_ · Jan 08, 2015 at 12:17 AM 0
Share

Have you tried clamping xSpeed at the end of OnCollisionEnter2D as it may be called multiple times if multiple objects are collided (or if you have multiple colliders components on 1 gameobject). It should not set xSpeed to 0 though, but maybe very close.

Also, did you try some edge cases with the physics2d project settings, like changing velocity & position iteration to 1 and next to 20. This would be to see if it helps reproduce the bug more often or remove it. You could also play with the time settings to increase & decrease the frequency of fixedupdates: it may also trigger the bug more or less often and give new leads.

avatar image DamDamDuSixZero · Jan 08, 2015 at 06:07 PM 0
Share

Hmm like i say in my first post, when the bug occurs my velocity is set to the right value at the end of the update, but when the update start again the velocity is set to 0. So clamping value doesn't do anything.

But Ill give a try for your second idea. I'm not totaly satisfied tough because it doesn't solve the bug, but it's a good idea for the moment.

Do you think I can re-use addforce for Jump, and direct change to velocity for the x movement ? The bug still occurs without addforce but I think it makes it appearing less often.

avatar image _dns_ · Jan 08, 2015 at 11:12 PM 0
Share

AddForce will only do some math to compute a new velocity, just like you do, so there is no problem using it. It will also take mass and deltaTime into account depending on the force mode.

The important thing is when to call it and to make it work with the other parts of your code. This page : http://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.html has very interesting information about that. You'll see that the physics engine will do it's computations just after the FixedUpdate and call the OnCollision/Trigger then. So, the best time to add forces is to do it during the FU because there will be as many FU as physics engine call. Inputs are updated during Update though, making things a bit more complicated if you want to be accurate and all framerate proof (= set a playerWantsToJump = true in Update, and use+clear it in FU)

For the bug you have, it must be the physics engine that sets the velocity to 0, possible cause is a collision that would stop the object. There must be a special situation to trigger that, multiple collisions at the same time or sometime a collision with an object that is 0.0001 further/upper/lower than it should be, or some math imprecision. $$anonymous$$y experience is that physics always need lots of tweaking, special case handling, faking reality etc... Your code seems correct so it may be difficult to track this bug. $$anonymous$$aybe you could backup all values like positions and velocity of your player at the end of the FU. Then, if you detect a 0 velocity in the update, you can use those backuped values to reproduce the exact situation that lead to the bug. This may help you to "pause" the game at the bug moment and inspect things to find the cause.

Also, it's totally normal to have this kind of problem while developing a game, spending lots of time debugging, even for the most experienced of us :-)

Show more comments

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Velocity powered rigidbody on a moving platform without parenting. 3 Answers

Ball stuck horizontally between rackets in pong 0 Answers

Troublesome collision detection when changing rigidbody.velocity directly 0 Answers

Why ForceMode.VelocityChange is inconsistent and how to fix it? 2 Answers

rigidbody2D.velocity.y not recording C# 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