- Home /
How to add collision detection between two game objects?
Hello,
I am remaking Pong as an practice exercise and right now I have the paddles moving correctly and the ball is also moving using the physics engine. However, I need a force to be added to the ball when it collides with one of the paddles. Right now the code that I have for the OnCollisionEnter2D method is adding to the velocity but it adds so much that the ball moves too fast and it stops colliding with the paddle. Would I need to use rigidbody2D.AddForce and not rigidbody2D.velocity?
using UnityEngine; using System.Collections;
public class Ball : MonoBehaviour {
float ballSpeed = 50;
float timeWait = 0.3f;
float multiplier = .5f;
// Use this for initialization
IEnumerator Start () {
yield return new WaitForSeconds (timeWait);
GoBall ();
}
void OnCollisionEnter2D(Collision2D collision){
if (collision.collider.tag == "PlayerOffense") {
rigidbody2D.velocity += rigidbody2D.velocity * multiplier;
}
}
IEnumerator ResetBall () {
rigidbody2D.velocity = new Vector2 (0, 0);
transform.position = new Vector2 (0, 0);
yield return new WaitForSeconds (1);
GoBall ();
}
void GoBall() {
float randomNumber = Random.Range (0, 2);
if (randomNumber <= 0.5) {
rigidbody2D.AddForce (new Vector2 (ballSpeed, 10));
} else
{ rigidbody2D.AddForce (new Vector2 (-ballSpeed, -10)); } } }
Answer by KaeTheDev · May 01, 2014 at 08:15 AM
Hello, Clonkex. Thank you for answering.
I am making the game just like the original so the X is the left-right. I actually already added the bouncy material to the ball but after so long the ball loses its force/velocity and falls to the bottom. I am going to work with the solution you gave me and get back to you.
Thank you again
I'm glad you've got something to work with :) However, you should not post a new answer as a reply to my answer. Ins$$anonymous$$d, you should have posted a comment on my answer.
$$anonymous$$y apologies. I'm new to the forum. Still getting the hang of things. I'm trying to work out your solution but i'm receiving errors. I know from experience you can't just assign x or y a value directly in C#. I have to use new Vector2. Your code would be
rigidbody2d.velocity = new Vector2(-rigidbody2D.velocity.x,0);
But when I tried this the ball collided with the paddle and stuck to it ins$$anonymous$$d.
It's not really a forum, more a Q&A site, but that's ok; you gotta start somewhere, right?
Ah, yes. That was one thing I thought of but hoped it wouldn't happen. What's happening is that when the ball collides with the paddle, it slightly moves inside the paddle. Its speed is reversed, but before it leaves the paddle, the next frame comes around and because it's still inside the paddle, its speed is reversed again. This basically makes the ball stick to the paddle.
SO. What I now recommend is that you go back to using your old code, where you just had a bouncy material on the paddles and the ball was physically simulated. If you find the ball falls downwards while it's moving, make sure to disable gravity in its properties. Then, to make sure it never slows down, in Update()
, do something like this (bearing in $$anonymous$$d I don't know C#, only JS):
if($$anonymous$$athf.Abs(rigidbody2D.velocity.X)<$$anonymous$$speed)
{
rigidbody2D.velocity=new Vector2($$anonymous$$speed,rigidbody2D.velocity.Y);
}
I'll modify my answer.
Got it. And yes, you do have to start somewhere ^_^
Okay, i've been tinkering with the code and it works but there was still a problem: after so many collisions with the paddle the ball bounces at uncontrollable speeds.
I changed the line:
rigidbody2D.velocity += rigidbody2D.velocity * multiplier;
To:
rigidbody2D.velocity *= multiplier;
This stopped the ball from speeding up uncontrollably but it still gets stuck slightly when colliding with the paddles.
Oops, forgot to actually modify my answer like a said I would. As I say, my recommendation is to simply limit the max velocity, so the ball CAN'T go too fast. Check if the velocity is above a certain amount and if it is, set the velocity back to that certain amount. Refer to my previous comment, and as soon as I edit it, my answer.
Answer by Clonkex · May 01, 2014 at 03:30 AM
There's a couple of ways you could do this. The first one that comes to mind is to simply negate the X velocity (assuming X is left-right) when it collides with either paddle. Something like this:
void OnCollisionEnter2D(Collision2D collision){
if (collision.collider.tag == "PlayerOffense") {
rigidbody2D.velocity.X = -rigidbody2D.velocity.X;
}
}
The other way I can think of doing would be to physically simulate the paddles and ball, so you don't manually change any velocities or modify forces, it just bounces. However, you would have to also set up a physics material for either the ball or the paddles to make it bouncy and create physical walls at the edges of the screen. To stop the ball just falling away, you would freeze movement on the Y axis and turn off gravity. Probably easier and more controllable to use the first method.
EDIT:
Ah, there's a problem with the code I posted above. What's happening is that when the ball collides with the paddle, it slightly moves inside the paddle. Its speed is reversed, but before it leaves the paddle, the next frame comes around and because it's still inside the paddle, its speed is reversed again. This basically makes the ball stick to the paddle.
SO. What I now recommend is that you go back to using your old code, where you just had a bouncy material on the paddles and the ball was physically simulated. If you find the ball falls downwards while it's moving, make sure to disable gravity in its properties. Then, to make sure it never slows down, in Update(), do something like this (bearing in mind I don't know C#, only JS):
if(Mathf.Abs(rigidbody2D.velocity.X)<minspeed)
{
rigidbody2D.velocity=new Vector2(minspeed,rigidbody2D.velocity.Y);
}
If you have any more questions feel free to comment and I'll do my best to explain further :)
Your answer
![](https://koobas.hobune.stream/wayback/20220613144000im_/https://answers.unity.com/themes/thub/images/avi.jpg)