Search Unity

Object slows down after each collision

Discussion in 'Physics' started by mpriem, Jan 12, 2017.

  1. mpriem

    mpriem

    Joined:
    Dec 31, 2016
    Posts:
    9
    Hi All,

    First post here on the Unity forum. I'm new to Unity and have been working on a Arkanoid clone for a few weeks now. It is almost done, but there is one anoying issue I cannot get my head around.

    My ball slows down after each collision with my borders or block, meaning the game gets slower over time.
    I have set the project gravity to 0, I have set the friction on my PhysicsMaterial2D to 0, I have no linear or angular drag on the balls Rigidbody2D.

    Aside from setting the initial velocity on the ball when the game starts I have disabled all other modifications to the balls velocity. For completeness I have copied the ball script code below.

    I hope someone can help me finalize this game!

    Thanks a million in advance!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Ball : MonoBehaviour {
    6.     private Player player;
    7.     private bool hasStarted = false;
    8.     private Vector3 relativePosition;
    9.     public float startVelocity;
    10.     private Vector2 lastCollisionPosition;
    11.  
    12.  
    13.     void Start () {
    14.         player = GameObject.FindObjectOfType<Player>();
    15.         relativePosition = this.transform.position - player.transform.position;
    16.     }
    17.  
    18.  
    19.     void FixedUpdate () {
    20.         if (!hasStarted)
    21.         {
    22.             this.transform.position = player.transform.position + relativePosition;
    23.             if (Input.GetMouseButtonDown(0))
    24.             {
    25.                 hasStarted = true;
    26.                 this.GetComponent<Rigidbody2D>().velocity = new Vector2(2f, startVelocity);
    27.             }
    28.         }
    29.         Debug.Log(this.GetComponent<Rigidbody2D>().velocity.magnitude);
    30.  
    31.  
    32.     }
    33.  
    34.     Vector2 getAdjustment()
    35.     {
    36.         Vector2 currentPosition = this.transform.position;
    37.         float x = 0;
    38.         float y = 0;
    39.         if (lastCollisionPosition.x == currentPosition.x)
    40.         {
    41.             if (currentPosition.x >= 8f) {
    42.                 x = -1f;
    43.             }
    44.             else{
    45.                 x = 1f;
    46.             }
    47.         }
    48.         else if(lastCollisionPosition.y == currentPosition.y){
    49.             if (currentPosition.y >= 6f)
    50.             {
    51.                 y = -1f;
    52.             }
    53.             else {
    54.                 y = 1f;
    55.             }
    56.         }
    57.         Vector2 adjustment = new Vector2(x, y);
    58.         return adjustment;
    59.     }
    60.  
    61.  
    62.     void OnCollisionEnter2D (Collision2D collision) {
    63.         if (hasStarted) {
    64.             Vector2 adjustment = getAdjustment();
    65.            // this.GetComponent<Rigidbody2D>().velocity += adjustment;
    66.             lastCollisionPosition = this.transform.position;
    67.         }
    68.     }
    69.  
    70. }
     
    Last edited: Jan 13, 2017
  2. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Is the ball's velocity supposed to be constant? You might do something like this:
    Code (CSharp):
    1.  
    2.  Vector2 v = GetComponent<Rigidbody2D>().velocity;
    3.   v = v.normalized;
    4.   v *= speed;
    5.   GetComponent<Rigidbody2D>().velocity = v;
    6.  
    This should give you a constant velocity (actually if the velocity becomes zero it won't work, so that will need a special case).

    Are you using the bounce part of the PhysicsMaterial2D?
     
  3. mpriem

    mpriem

    Joined:
    Dec 31, 2016
    Posts:
    9
    Hey, thanks for your reply. The ball has a physicsmaterial2d with bounciness of 1 and friction of 0. The speed should be constant. I just cannot figure out why a collision would reduce the velocity after the bounce. I have no material attached to any other game object, so this should mean the colliders should have zero additional effect on my ball, right? I see that there is a default friction of 0.4 on my colliders in the info pane on the inspector but from what I read that does not apply due to not having a material.

    I will try your code, but would also want to understand where that loss of velocity comes from.
     
  4. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Just to test, I set up a scene with four walls and a ball. I used a physicsmaterial2d on the walls with friction 0 and bounce 1. On the ball I placed a physicsmaterial2d with both values set to zero. I did freeze the rotation in Z on the ball, since this can sometime cause "problems" (but since the friction is zero, this shouldn't be an issue here).

    Then I wrote a script which set the balls velocity to (5, 5) in Start() and the only thing I did in Update was Debug.Log(rb.velocity.magnitude).

    I ran it for several minutes and had no difference in velocity. Well, it did switch between two speeds, but the values were so close that it is probably due to a rounding error from the floating point.

    So, in my case I didn't experience any loss in velocity due to collisions.
     
  5. mpriem

    mpriem

    Joined:
    Dec 31, 2016
    Posts:
    9
    The difference being I don't have materials set on the walls and blocks, just on the ball. Let me test by adding materials to the walls and get back to you. Logically reasoning it doesn't make sense if that works, but it's worth a try.
     
  6. mpriem

    mpriem

    Joined:
    Dec 31, 2016
    Posts:
    9
    Ok so the problem is solved, but there is no explanation.

    I tried adding the materials to the walls. Did not work. I removed the material from my ball prefab. Created a new one, added it back, problem solved :)

    Removed the new material, put back the old, no repro...

    Seems like a small Unity bug I ran into....

    Well I'm glad my understanding of the physics engines response to gravity, bounciness, friction, drag, and velocity is still valid.

    Thanks for your help @PGJ !!!
     
  7. pradip_spixel

    pradip_spixel

    Joined:
    Jul 11, 2018
    Posts:
    3
    what is speed??? it shows error
     
  8. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Well, I guess, it would have been better to call it velocity. It's the speed you want your object to move at. Create a variable called speed and set it to the velocity you want the object to move at. Try to set it to 1 and then change it from there until you get the velocity you feel is right...
     
  9. kobyfr

    kobyfr

    Joined:
    Aug 21, 2020
    Posts:
    7
    the bricks and walls should be kinematic and static. See image please.
    upload_2020-10-23_16-29-14.png
    Also, set the velocity threshold in the Physics 2D settings to 0 (which will get it set to the minimum, probably 0.0001).
     
    yoshii_minami likes this.
  10. RektByGrub

    RektByGrub

    Joined:
    Aug 19, 2019
    Posts:
    4
    Had the exact same issue, with a same kind of game. :)

    I wonder if you are watching the same course on Udemy I am.

    Either way, removing the material and re-adding it fixed for me too.

    How odd.

    I have also tried PGJ's debug, and noticed the number dropping pre-recreation of the material, but stay constant after!

    Hmmm, call it a bug?
     
  11. powerfrost

    powerfrost

    Joined:
    Dec 15, 2020
    Posts:
    1
    I changed the friction of my ball and block to 0 and it works great. Just create a new physics material 2D and set the friction to zero, and apply to all your blocks. Same with ball (with ball you would need to add bounciness).
     
  12. yoshii_minami

    yoshii_minami

    Joined:
    Mar 29, 2021
    Posts:
    1
    This is the definite solution for me