Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
1
Question by Eradan · Feb 18, 2017 at 02:09 PM · physicscontact.pointlate

Collision contact point check is late on physics

I'm making a breakout/arkanoid clone. Here's the logic of the ball movement:

  • I have a normalized vector3 called "direction" (its Z axis is always 0 since the ball moves on the X/Y plane)

  • Movement is set every fixed update with a Rigidbody.velocity assignment = direction * speed (int)

  • If a collision is detected the script takes the position of the collision relative to the ball (contactVector = Collision.contact.point - transform.position).

  • A check on this vector is made (INSIDE the collision function) and if contactVector.x or contactVector.y are != 0 then that axis is inverted in the original direction vector, bouncing the ball on bricks and walls.

I think that the logic is solid and it should work fine, but it doesn't. What I get is a velocity change of BOTH axis, always.

If i print the contactVector value of a, let's say, contact on the right wall I can see that the x value is fine (= to the sphere radius) but the value on the other axis is NOT zero. This non-zero value is proportional to the ball speed and its sign is opposite of the velocity. This means that the concactVector is calculated AFTER the collision. Why is that? I don't want to find a workaround about this issue, I'm here to learn how things work.

This is the code, I'm sorry if it's a bit messy (please ignore the player part), I hope someone can help me understand:

 public class Ball : MonoBehaviour {
 
     Rigidbody rb;
     public float speed;
     Vector3 direction;
     [Range (0, Mathf.PI/4)]
     public float maxAngle;
     float angle;
     float playerSize;
     public GameObject player;
 
     // Use this for initialization
     void Start () 
     {
         rb = GetComponent<Rigidbody> ();
         direction = new Vector3 (1, 1, 0f).normalized;
     }
     
     // Update is called once per frame
     void Update () 
     {
         rb.velocity = speed * direction;
     }
 
     void OnCollisionEnter(Collision hit)
     {
         ContactPoint contactPoint = hit.contacts[0];
         Vector3 contactDir = contactPoint.point - transform.position;
         if (hit.gameObject.tag == "Player") 
         {
             Vector3 contactPlayer = contactPoint.point - player.transform.position;
             playerSize = player.GetComponent<Collider> ().bounds.size.x / 2;
             angle = Mathf.PI / 2 -Mathf.Sign(contactPlayer.x) * Mathf.Abs(maxAngle * contactPlayer.x / playerSize);
             direction = new Vector3 (Mathf.Cos(angle), Mathf.Sin(angle), 0f);
         }
         else 
         {
             if (hit.gameObject.tag == "Bricks")
                 Destroy (hit.gameObject);
             if (Mathf.Abs (contactDir.x) != 0)
                 direction.x *= -1;
             if (Mathf.Abs (contactDir.y) != 0)
                 direction.y *= -1;
             Debug.Log (contactDir);
         }
     }
 
 
 }



Comment
Add comment · Show 6
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
avatar image _dns_ · Feb 18, 2017 at 10:20 PM 0
Share

Hi, a physics engine is never exactly accurate. You might get better results with settings the "continuous" collision flag on your objects' rigidbodies. Changing the physics settings may help get a more accurate result too (Solver iterations, solver velocity iterations) but will cost more CPU, it's often a trade off. For a more high level explanation, check wikipedia here: https://en.wikipedia.org/wiki/Collision_detection#A_posteriori_.28discrete.29_versus_a_priori_.28continuous.29

avatar image Eradan · Feb 20, 2017 at 10:24 AM 0
Share

So, I could I get a precise result here? Are there alternative common practices to achieve what I'm trying? Thanks for the interesting info. (I've already tried to change the collision method in the rigidbody, with no luck).

avatar image _dns_ Eradan · Feb 21, 2017 at 03:56 AM 0
Share

Usually, you just let the physics engine detect collisions and compute collision responses. In your case, in Start() you setup the initial velocity using rb.velocity or AddForce. $$anonymous$$ake sure you also setup a physics material with correct bounce value for all object. If you want to make sure the speed is stable, in each FixedUpdate() (the physics engine is updated just after all FixedUpdate() are called, not Update()) you can normalize the rb.velocity & multiply it by speed. Events like OnCollisionEnter() are usually used to manage gameplay events, like damaging a brick or playing a sound.

The collisions may not be perfect but should be good enough for a game. I don't know the 2D physics engine a lot but maybe it's more accurate because things are simpler in 2D (and it's based on another engine). You can still make some 3D objects child of the 2D objects containing the colliders & rigidbody2D, gameplay is 2D but representation is still 3D.

If you want a perfect solution with exact contact points, you'll have to manage raycasts yourself but that's more advanced coding and there is usually no reasons to do that :-) but maybe you have one ?

btw, there is a tutorial for a breakout game here: https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/creating-a-breakout-game

avatar image RobAnthem · Feb 21, 2017 at 05:51 AM 0
Share

This doesn't make sense to me, the physics for a ball already work as they should. Have you tried making a physics material for your ball that contains the appropriate bounce you want? Unitys physics engine already takes into account velocities, direction, force. and mass.

avatar image Eradan RobAnthem · Feb 21, 2017 at 03:25 PM 0
Share

Yes, but since I had to modify the bounce once the ball hits the player's bar I wanted to manage everything from script. Now I get how that's impossibile.

avatar image _dns_ · Feb 21, 2017 at 04:07 PM 1
Share

Well, if you want to have a custom reaction, you'll need a custom solution. This is a classic with game engines, it never does exactly what we want :-) So, some trick i used some time ago to get precise collisions with a sphere/circle: imagine a rectangle, now, ins$$anonymous$$d of colliding a circle with this rectangle, imagine colliding a point with the rectangle: what shape would the rectangle have to have so that the point would react exactly like the center of a circle colliding with it ? The idea is to replace the circle by a point so it's easy to raycast it's movement, as the trajectory of a point is a line (or a curve if gravity is involved but it can always be approximated by a line). Now, imagine you scale the rectangle by exactly the circle radius = each of the 4 lines will be pushed by radius unit. We then have the exact same situation: point vs extended rectangle = circle with regular rectangle. There is a problem at the corners though: those must become circle ins$$anonymous$$d of points so a point/line colliding with them would react line a circle colliding a point/corner. Now, ins$$anonymous$$d of having a rectangle, you can have 2 rectangles, each one scaled in X or Y (not both) to extend them by the radius of the circle. Place 4 circle collider at each corner of the original rectangle. Now, you can use raycast from the center of the ball to the direction of it's velocity * fixeddeltatime. The position of the raycast hit should be very accurate. You now have to compute the new velocity. The difficulty is to know which collider was hit but you can test it's type (circle or rectangle, returned by the raycast functions) and compute the reaction from that. This is applicable to 3D as well, it can leads to lots of colliders though (but if they are static, unity will optimize computations). This concept can also be applied to other shapes, maybe using capsule colliders can be better in 3D. Well, I hope you get the idea, try drawing it on paper, it should be clearer :)

0 Replies

· Add your reply
  • Sort: 

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.

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

2D 360 degress platformer example needed 0 Answers

Ball physics and camera rotation determined by ball's collision contact normal 0 Answers

Softbodies in Unity 3D 1 Answer

Double Jump Physics 1 Answer

Help with 2D physics script 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