Object slows down after each collision

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!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ball : MonoBehaviour {
    private Player player;
    private bool hasStarted = false;
    private Vector3 relativePosition;
    public float startVelocity;
    private Vector2 lastCollisionPosition;


    void Start () {
        player = GameObject.FindObjectOfType<Player>();
        relativePosition = this.transform.position - player.transform.position;
    }


    void FixedUpdate () {
        if (!hasStarted)
        {
            this.transform.position = player.transform.position + relativePosition;
            if (Input.GetMouseButtonDown(0))
            {
                hasStarted = true;
                this.GetComponent<Rigidbody2D>().velocity = new Vector2(2f, startVelocity);
            }
        }
        Debug.Log(this.GetComponent<Rigidbody2D>().velocity.magnitude);


    }

    Vector2 getAdjustment()
    {
        Vector2 currentPosition = this.transform.position;
        float x = 0;
        float y = 0;
        if (lastCollisionPosition.x == currentPosition.x)
        {
            if (currentPosition.x >= 8f) {
                x = -1f;
            }
            else{
                x = 1f;
            }
        }
        else if(lastCollisionPosition.y == currentPosition.y){
            if (currentPosition.y >= 6f)
            {
                y = -1f;
            }
            else {
                y = 1f;
            }
        }
        Vector2 adjustment = new Vector2(x, y);
        return adjustment;
    }


    void OnCollisionEnter2D (Collision2D collision) {
        if (hasStarted) {
            Vector2 adjustment = getAdjustment();
           // this.GetComponent<Rigidbody2D>().velocity += adjustment;
            lastCollisionPosition = this.transform.position;
        }
    }

}
1 Like

Is the ball’s velocity supposed to be constant? You might do something like this:

 Vector2 v = GetComponent<Rigidbody2D>().velocity;
  v = v.normalized;
  v *= speed;
  GetComponent<Rigidbody2D>().velocity = v;

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?

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.

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.

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.

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 :slight_smile:

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_1 !!!

what is speed??? it shows error

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…

the bricks and walls should be kinematic and static. See image please.


Also, set the velocity threshold in the Physics 2D settings to 0 (which will get it set to the minimum, probably 0.0001).

2 Likes

Had the exact same issue, with a same kind of game. :slight_smile:

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?

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).

This is the definite solution for me