• 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 vProject · May 14, 2017 at 07:30 PM · jump2d-physicscollision2dcontact.point

How to use contact data from simultaneous collisions?

I have a ball that bounces the opposite way to a contact point (jumpPoint) when I press Jump.

The problem I am having is that if the ball has 2 contacts (either on the same object or on two separate objects), it only jumps away from the first contact point. Is there a way to calculate all contacts points with the ball from every object and work out the correct jump angle.

alt text

I have tried the 2 following methods: (all variables are vector2's. Most of the math here is done in Update rather than collision, I've just included it here to better show whats going on)

1:

 void OnCollisionStay2D(Collision2D other)
 {
     ballPos = transform.position;
     contact1 = other.contacts[0].point;
     output = conact1 - ballPos;
     jumpPoint = -output.normalized;
 }

2:

 void OnCollisionEnter2D(Collision2D other)
 {
     foreach (ContactPoint2D contact in other.contacts)
     {
         ballPos = transform.position;
         contact1 = contact.point;
         output = dir2 - dir1;
         jumpPoint = -output.normalized;
     }

Comment
Add comment
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

3 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Fritsl · May 14, 2017 at 07:58 PM

What do you do to add force? Because if you use physics, and just add all of it in fixedupdate, basically that should be it.

Else, maybe you can supply a little more info on the game and why you chose the setup you have?

Comment
Add comment · Show 7 · 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
avatar image vProject · May 15, 2017 at 11:18 PM 0
Share

Sorry for the late reply, my browsers were causing a lot of problems with unity answers.

The way I add force is fine, the script works in most situations, I have narrowed down the issue: The problem I am having is that if the ball is in contact with 2 separate colliders (as apposed 2 contact.points on the same collider), the script doesn't work, I believe that each different collision2D "other" is making a new instance, and I am unsure how to access the contact.points of the different instances. Here is my code (updated from last time):

 void OnCollisionEnter2D(Collision2D other)
  {
      contactCount = other.contacts.Length;
 
      if (contactCount == 1)
      {
          contactPos = other.contacts[0].normal;
      }
      else if (contactCount == 2)
      {
          contactPos = (other.contacts[0].normal + other.contacts[1].normal) / 2;
      }
  }

alt text

Really, I am looking to see if there is a way to access the second version of Collision2D other that is being made. I will count how many version of other there are, and average the contact.point normal provided by each version of other. I am unsure if this is the correct solution, but I have been testing it for days and this seems to be the problem. Thankyou for the reply to my original question.

avatar image NoBrainer-David vProject · May 16, 2017 at 08:32 AM 0
Share

Check out the Execution order of the Physics frame here: https://docs.unity3d.com/$$anonymous$$anual/ExecutionOrder.html

All collision calls are made before the next FixedUpate. What you could do, is have a List of Collision2Ds in which you collect all the collision calls from the OnCollision functions. Then, on the next FixedUpdate, you work through that list and then clear it.

Would that solve your problem?

avatar image vProject NoBrainer-David · May 16, 2017 at 05:57 PM 0
Share

Thankyou, I will give this a try. It is pretty strange that there isn't a simpler way to get all the contact info regardless of how many and which colliders are in contact with the ball.

The contact info of the ball in the inspector shows the exact data I need in a useful array, that would be perfect. Thanks for the reply.

Show more comments
avatar image Fritsl · May 16, 2017 at 08:18 AM 0
Share

I think there's something fundamentally wrong here: I'm not sure you'll get great results out of adding 2 normals and then divide by 2.

There's I$$anonymous$$O some strange things here, but it might be something you have thought about that I cannot see. But at least: You'll need to normalize your result after you have /2

$$anonymous$$aybe that'll fix it?

Under all circumstances I'd not do If 1, then this, if 2 then that, but always take everything and make that work ;)

avatar image vProject Fritsl · May 16, 2017 at 05:55 PM 0
Share

Sorry, I should have said, the resulting vector is normalized. The problem I am having isn't in calculating the correct jump vector / direction. The problem I am having is in getting the contact.normals from each collision.other.

Each collider the ball collides with produces and array of contact points, to get the correct direction the jump force needs to be applied in, I just take the average of the contact.normals, and normalize. This method works fine for getting multiple contact.normals from the same collider. However, this method doesn't work in getting contact.normals from multiple colliders at the same time. Is there a way to access the contact.normal array of each all colliders the ball is in contact with. Thankyou for the reply :)

avatar image
0

Answer by vProject · May 18, 2017 at 12:37 AM

TO: Fritsl

The site has been bugged for me for days I'm afraid, I can't reply to you directly Fritsl, but seem to be able to reply to the question as a whole, so I hope you see this.

The way I add force works fine:

 myRigidBody.AddForce(jumpPoint * force, ForceMode2D.Impulse);

It's the calculation of the jump direction, jumpPoint, thats the problem. Is there a way to get the contact data of each instance of Collision2D other, because right now if the ball in contact with more than one instances of "other" it will choose one of them at random as the object to bounce off.

In addition to this, there are cases where the ball can have more than one contact point with a single object. I know this produces an array, but I am unsure how to use this array correctly. I feel like I need something like the following, but am unsure how to implement it correctly:

 If (contact.point.amount = 1)
 {
     contact1 = other.contacts[0].point;
 }
 else if (contact.point.amount = 2)
 {
     contact1 = other.contacts[0].point + other.contacts[1].point;
 }
Comment
Add comment · Show 2 · 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
avatar image Fritsl · May 18, 2017 at 11:25 AM 0
Share

I'm sorry but it's hard to get any much closer when not having the project to hammer ;)

Here's a couple of pointers - things you may or may not know, but the tools I'd look at, I would think:

A) If you have a 'Direction Vector' - as often the result of 'Normal', it is a normalized vector. If you have a transform position, and add the Direction Vector to that, you have .. a direction: Example Direction Vector: (0,1,0) Position: (0,0,0) Result: (0,1,0).

B) If you multiply your direction with 100, add it to position and draw a line from your position to that direction, you get a 100 units long line.

https://docs.unity3d.com/ScriptReference/Debug.DrawLine.html

Visualizing what is going on is key.

So I'd set up a visual indication of ALL the variables at stake: Red for [0], Blue for [1] Green for Calculated etc.

Then play game, and you will be able to see in Editor what all your variables are trying to do.

I hope that helps ;)

avatar image vProject Fritsl · May 20, 2017 at 11:43 AM 0
Share

You have been a big help. I have sorted the problem now with a mix of help form you and DerDude. Thankyou very much.

avatar image
0

Answer by Raptosauru5 · Apr 12, 2020 at 11:29 AM

vProject: Would you mind posting the solution you came up with please? This forum does not allow users to directly message each other (which I think is stupid, especially for the cases where the problem got solved but was not shared) Thanks in advance, if you read this

Comment
Add comment · 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.

Follow this Question

Answers Answers and Comments

7 People are following this question.

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

Related Questions

Trigger not being activated? 1 Answer

2D collisions not showing all contact points 0 Answers

How can i detect how many objects of the same type i'm triggering and choose only one of them? 1 Answer

OnCollisionEnter2D in a puzzle game with each block snapped to a grid? 1 Answer

Collider2D.GetContacts(List() contacts) works with OnColliderEnter2D but not with OnTriggerEnter2D 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