1
\$\begingroup\$

I am trying (and believing) to make a game of pong. I have got a slightly decent working game. I haven't implemented the scoreboard or AI yet because I want the physics to work first. I am trying to reverse the direction of the ball when it hits either paddle just to make it work cleanly and am having the issue where it changes direction twice, it bounces off the paddle as expected and then goes in the opposite direction to when it hit the paddle -.- If anyone could help me, it would be much appreciated.

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

    public class BallController : MonoBehaviour {

        private float randomNumber;
        private float range;
        private float pointOfContact;
        private float paddleTop;
        private float paddleBottom;
        private float[] limits;
        private int speed;
        private int caseNumber;
        private Vector2 direction;
        private Rigidbody2D ballRigidbody;

        void Start () {
            //Getcomponent finds the rigidbody of the attached object.
            ballRigidbody = GetComponent<Rigidbody2D> ();

            speed = 5;
            caseNumber = Random.Range (0, 2);
            range = PickARange (caseNumber);
            ballDirection (speed, range);
        }

        void FixedUpdate() {

        }

        void OnCollisionEnter2D (Collision2D coll) {
            if (coll.gameObject.tag == "Player" || coll.gameObject.tag == "Computer") {
    //          pointOfContact = ballRigidbody.position.y;
    //          print (pointOfContact);

                ballRigidbody.velocity = new Vector2 (ballRigidbody.velocity.x, ballRigidbody.velocity.y * -1);
            }
        }

        void ballDirection (int ballSpeed, float yDirection) {
            randomNumber = (Random.Range (0, 100));

            if (randomNumber < 49) {
                direction = new Vector2(Random.Range (-1.0f, -0.5f), yDirection);
                ballRigidbody.velocity = (direction * ballSpeed);
            } else {
                direction = new Vector2(Random.Range (0.5f, 1.0f), yDirection);
                ballRigidbody.velocity = (direction * ballSpeed);
            }
        }

        float PickARange (int number) {
            switch (number) {
            case(0):
                range = Random.Range (0.5f, 1.0f);
                return range;
            case(1):
                range = Random.Range (-1.0f, -0.5f);
                return range;
            default:
                range = 1.0f;
                return range;
            }   
        }
    }

I thought to multiply the whole velocity by -1 but that just caused a loop because of the lag. Even though that's the right way to reverse the direction. I think.

Thanks Peeps!

\$\endgroup\$
  • \$\begingroup\$ Normally the collision itself will deflect the velocity, so you might be double-reflecting here, countering the physics engine's own bounce. What do you get without this collision handler? \$\endgroup\$ – DMGregory Feb 28 '18 at 19:26
  • \$\begingroup\$ That does make a lot of sense. I thought however, that this collision handler would override any original collisions. I do get a normal collision without it. I can also increase the speed of the ball after the collision without the lag. If I changed the angle I might still get the lag however, any suggestions on how to fix it? Thanks very much for the help by the way!! Also, is there a way to follow your own posts and get notifications of replies? I stopped coding last night because I was trying all day to make the game and thought I'd get an email if anyone replied. \$\endgroup\$ – Bowcox Mar 1 '18 at 10:08
  • \$\begingroup\$ Please don't edit a question that already has answers to change it into a different question. Asking new questions is free, so just post a new one when you want to learn something new. You can link to your previous question for context. \$\endgroup\$ – DMGregory Mar 1 '18 at 23:58
2
\$\begingroup\$

OnCollisionEnter(Collision collision) handlers run after the physics engine has resolved the collision by displacing the objects and updating their velocities.

That means that at this moment, the ball has already bounced off the wall/paddle, and reversing its velocity will tend to send it back into collision which can cause it to linger in contact and look like it's lagging/stalled. The game's still running at normal speed, but the ball is changing direction too frequently to make progress until, by some luck, it eventually lands outside of collision and can continue on its way.

If you want to control your velocity after a bounce, the Collision argument contains information about the impact that you can use.

Specifically, if the collider you hit was not itself moving, then:

var preCollisionVelocity = -1f * collision.relativeVelocity;

will give you your incoming velocity, before the collision resolver ran. You can safely use that as the source to reflect from.

Just note that an object might experience several collisions in a single physics step, so you'll want to watch out for literal corner cases where you've reflected off two or more surfaces in rapid succession.

\$\endgroup\$
  • \$\begingroup\$ Thanks for clearing up a lot for me. The first two paragraphs helped a bunch. I was just wondering whether you could help me with understanding Dynamic and Kinematic, I've looked on the APIs but am still struggling. I am also still struggling after using the above to correct the issue and wondered whether it was linked in any way to the Body Type property? Thanks again! \$\endgroup\$ – Bowcox Mar 1 '18 at 21:12
  • \$\begingroup\$ That sounds like a new question to me. :) \$\endgroup\$ – DMGregory Mar 1 '18 at 21:20
  • \$\begingroup\$ I'm so sorry haha. I have been working on it for hours, trying different things to make it work as I want it to and that's the only thing I can think of that links to the physics that's causing the problem. I've looked all over google for people with a similar situation to me, asking others and you're the only one who responded. You're my god xD \$\endgroup\$ – Bowcox Mar 1 '18 at 21:28
  • \$\begingroup\$ That's not true, prithul also offered suggestions. In any case, if you have a question about kinematic & dynamic bodies, post it as a new question and you can get answers to that. We don't do follow-up questions in the comments here, as it makes for a more convoluted & hard-to-follow thread. The one question --> one accepted answer format makes it much quicker to find solutions to problems. \$\endgroup\$ – DMGregory Mar 1 '18 at 22:12
  • \$\begingroup\$ Yeh, true, sorry. That's my bad for rushing to get to a solution, just have so little time with work as well. I apologise. I will definitely post a separate question. Thanks for the help however. \$\endgroup\$ – Bowcox Mar 1 '18 at 22:17
0
\$\begingroup\$
  • Have you checked whether OnCollisionEnter2D is invoked multiple times when a collision happens? If that is the case, it might be that Unity is detecting several points on the ball to have collided with the paddle. In that case, you can cause the ball to be immune to direction-change for a short amount of time.

  • Or it could be that you are negating the ball's direction after it has already changed its direction on collision.

\$\endgroup\$
  • \$\begingroup\$ I think that it's the second one because without it, it still collides as expected. Is there something you can suggest to fix this? Sorry, I'm new to coding in general and tried so hard yesterday haha. Thanks for the help by the way! \$\endgroup\$ – Bowcox Mar 1 '18 at 10:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.