• 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
Question by Sky0812 · Feb 23, 2019 at 05:59 AM · velocityballboxcollidercontact point

[SOLVED] 3D Ball in Breakout clone acts unpredictably when colliding with corners

alt text


This problem is slowly driving me insane. As shown in the gif, the ball of my breakout game will start to act strange if it hits the corner between two blocks, and this happens frequently. I manually set for the blocks to not get destroyed here, but when they can be destroyed and the ball hits the corner it basically moves through the 2 blocks it hit and then hits another block above it, allowing the ball the take out 3 or more blocks before bouncing off as intended. Clearly NOT ideal.


To be clear: This is a 3D scene with an orthographic camera, here's a view from the editor: alt text

At the start (and when re-spawning) the ball runs this code: transform.position = Vector3.zero; direction = new Vector3(Random.Range(-1f, 1f), 1f, 0f).normalized; GetComponent<Rigidbody>().velocity = direction * speed;.

Then in FixedUpdate it constantly runs this: GetComponent<Rigidbody>().velocity = direction * speed * Time.deltaTime * 50f;.

If the ball collides with a block then it calculates a new direction using foreach (ContactPoint contact in collision.contacts) { direction = Vector3.Reflect(direction, contact.normal); return; }


Things I've Already Tried: - Changing the ball to isKinematic and moving it with translation instead of the Rigidbody.velocity - Expanding the edges of the box colliders on the blocks - Forcing the contact.normal value to be (0, -1, 0), even when the ball hits a corner and the normal would be different - Setting the Physics "Default Contact Offset" to 0.0001 - Changing the ball's collision detection to "Continuous"


I'm at a loss as for what to try next to resolve this, so hopefully there's someone helpful out there who is willing to lend some insight!

breakout-collision.gif (173.7 kB)
breakout-scene.jpg (244.8 kB)
Comment

People who like this

0 Show 0
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

1 Reply

· Add your reply
  • Sort: 
avatar image

Answer by Sky0812 · Feb 23, 2019 at 09:17 PM

No thanks to verarpaulson with the ad... I finally found a fix.

The issue was with the Contact Points and the Vector3.Reflect, and setting the velocity on FixedUpdate. I removed all of that code and added a 'bouncy' material to the ball (bounciness 1, friction 0), and removed the rigidbodies that were on my blocks and walls. Evidently, having rigidbodies on the non-ball objects in the scene caused the ball to slow down a bit on each bounce. So only the ball and paddle have rigidbodies now. The paddle would also slow the ball down, except I re-calculate the ball's velocity each time it hits the paddle to have more control (ie: hitting on the left side of the paddle shoots the ball off to the left).


I'm sure I'll be adding more to the ball script when I get to power-ups, but for basic ball movement, bouncing, and re-spawning here's the code I used. I also put in some comments to explain what the different sections of the code is doing, so I hope this helps someone else in the future! *Note that this code will not run without a GameManager and Lives script! You can remove or comment out those lines and replace them with whatever you want.


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

public class Ball : MonoBehaviour { private Vector3 direction; private Rigidbody rb;

 public float speed = 5f;
 public GameObject paddleLeftEnd;
 public GameObject paddleRightEnd;   

 void Start()
 {
     rb = GetComponent<Rigidbody>();
     Respawn();             
 }

 //Spawn the ball and set starting direction
 public void Respawn()
 {
     //Set ball position at (0,0,0) in scene
     transform.position = Vector3.zero; 

     //Set ball velocity to random upwards direction
     direction = new Vector3(Random.Range(-1f, 1f), 1f, 0f).normalized;
     rb.velocity = direction * speed;
 }

 //Check for trigger with ZoneOut and update Lives
 public void OnTriggerEnter(Collider collider)
 {
     GameObject objectTriggered = collider.gameObject;

     if (objectTriggered.tag == "ZoneOut")
     {
         //Subtract a life and respawn ball
         GameManager.lives--;
         Lives.UpdateText();
         GameManager.CheckGameEnd();
         Respawn();
     }
 }

 //Check which object was hit and act accordingly
 void OnCollisionEnter(Collision collision)
 {
     //Store game object hit
     GameObject objectHit = collision.gameObject;

     if (objectHit.tag == "Paddle")
     {
         //Get y positions of ball and paddle
         float ballY = gameObject.transform.position.y;
         float paddleY = paddleLeftEnd.transform.position.y;
         //If ball is lower than the paddle, exit this method and
         //allow the ball to continue towards the screen bottom
         if (ballY < paddleY)
         {
             Debug.Log("Ball Under Paddle");
             return;
         }
         //Get x positions of ball and paddle end points
         float ballX = gameObject.transform.position.x;
         float p1 = paddleLeftEnd.transform.position.x;
         float p2 = paddleRightEnd.transform.position.x;           
         //Calculate the new value of x for the ball to be directed
         float PaddleLength = p2 - p1;
         float BallLocation = ballX - p1;
         float xDirection = ((BallLocation / PaddleLength) - 0.5f) * 5;
         //Set new ball direction
         direction = new Vector3(xDirection, 1f, 0f).normalized;
         rb.velocity = direction * speed;
     }
     else if (objectHit.tag == "Block")
     {
         //Destroy block hit and subtract block total           
         Destroy(objectHit);
         GameManager.blocks--;
         GameManager.CheckGameEnd();
     }

     //Check if the ball is moving mostly horizontally. If the ball is 
     //too horizontal, increase or decrease the Y direction accordingly
     if (rb.velocity.y < 1.5f && rb.velocity.y > 0f)
     {
         direction = new Vector3(direction.x, 0.2f, 0f);
         rb.velocity = direction * speed;
         Debug.Log("Horizontal Ball Averted");
     }
     if (rb.velocity.y > -1.5f && rb.velocity.y <= 0f)
     {
         direction = new Vector3(direction.x, -0.2f, 0f);
         rb.velocity = direction * speed;
         Debug.Log("Horizontal Ball Averted");
     }
 }

}

Comment

People who like this

0 Show 0 · 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

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

100 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to set ball velocity after it was hit with a racket in a tennis game? 0 Answers

Ball disappears after invoking a method 0 Answers

Bouncing Ball Game 3 Answers

Apply Gravity to Car Physics 0 Answers

[Solved] How to shoot an object in front of the player? 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