Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
9
Question by darbotron · Sep 08, 2013 at 08:24 PM · collision detectioncollision event

any way to get a pre-solve collision callback?

I have a AAA console gamedev background, so I'm used to having source access & I am finding myself immensely frustrated by what I can only describe as a missing feature in Unity's rigidbody collision behaviour.

Physics engines typically work in several passes per update, broadly speaking:

1) update all objects in the simulation based on forces / accelerations / impulses acting on them this step

2) check for collisions

3) resolve collisions

AFAIK all physics engines I have used have the concept of a 'pre-solve' collision callback/event - (i.e. after or during step 2 but before step 3). I assume that physx does, but couldn't find the SDK documentation online to check.

For example: Bullet - http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers#Contact_Callbacks

Box2d - http://www.box2d.org/manual.html#_Toc258082975

Having this event makes it very easy to detect all collisions but choose contextually on a collision by collision basis to ask the engine to ignore them (i.e. not to physically resolve them).

The important factor being that there are many gameplay reasons why for any given pair of objects the decision to ignore the contact, or not, might be based on information only available at the point that the contact is generated - i.e. immediately before the collision is resolved.

Assuming there isn't a unity event for this (which I am pretty confident it isn't as I have found no answers when I searched before writing this) then what is the "usual" workaround?

I'm anticipating some archaic combination of game objects having triggers that contain rigid bodies with colliders and additional logic, so would be very pleased if someone has an elegant solution :)

Regards, Alex

Comment
Add comment · Show 3
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 fherbst · Sep 09, 2013 at 12:51 AM 0
Share

That's actually a very good question, although I fear the best you can do is to make Raycasts for the objects where this might matter.

Could you write down a few of that "gameplay reasons", so we can get a better view of what you mean and what the appropriate Unity solution could be?

avatar image Fattie · Sep 09, 2013 at 08:29 AM 0
Share

there is the, to me, exceptionally confusing

Documentation/ScriptReference/Physics.IgnoreCollision.html

call, which may be relevant. you can see a few answers about it on here

avatar image darbotron · Sep 09, 2013 at 09:23 AM 1
Share

sorry for posting the same text in 2 places (see my comment on the answer below), but it seemed easier than typing approx. the same thing again :)

By 'ignoring' the collision I mean preventing the physics solver from resolving the collision - i.e. the engine detects the collision with full physics info generated, but then allows me to ask it to behave as if the collision didn't happen which would let the objects pass through each other.

Obviously it is possible to ignore collisions using layers or Physics.IgnoreCollision, but these approaches are limited in that (as far as I can tell) they only allow either:

  1. no collisions, or

  2. all collisions

between any two specific objects.

The behaviour I am trying to achieve requires me to know when physically simulated objects have collided, look at the SPECIFIC circumstances of that collision (e.g. relative velocities, relative positions, the specific objects involved and their state (time since spawning for example) etc.) and then if, and only if, the circumstances meet specific conditions ask the physics simulation to ignore the collision.

The classic example of this sort of behaviour is the platform that you can jump up through, but not fall down through in a platform game - what I'm trying to do is similar but relies on more than just the objects' relative positions etc.

3 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by Fattie · Sep 09, 2013 at 10:48 AM

Just to be clear Alex ... are you aware that it's "not too late" to call Physics.IgnoreCollision in OnCollision???

link text

Please launch the little project attached and run it.

alt text

Caveat - I've never really understood Physics.IgnoreCollision (perhaps because it's totally undocumented, "when" it happens) but it seems to work in cases like that. This may or may not help you in some way.


screen shot 2013-09-09 at 13.05.47.png (18.0 kB)
bounceteste.zip (100.3 kB)
Comment
Add comment · Show 14 · 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 darbotron · Sep 09, 2013 at 10:57 AM 0
Share

Nope, I was definitely not aware of that - as you say, that behaviour isn't documented.

That is almost the behaviour I was looking for, I still need to turn collisions between those objects back on again at some point which might be a pain in the bum...

Awesome, thanks. Will check out the project. $$anonymous$$uch appreciated.

avatar image Fattie · Sep 09, 2013 at 11:05 AM 1
Share

You know I really think this is the solution or factoid you were after, $$anonymous$$.

(This is "Common Situation #13" on this list. Someone, perhaps a seasoned-but-new-to-unity programmer, asks a question that has a relatively simple answer, but everyone assumes "oh, it can't just be that the OP wants to know X, what the hell else could it be." ... heh)

{The very most common Common Situation on this list is that a beginner asks how to do a timer (Invoke) but thinks you need to use yield ;-) }

Anyway yeah.

(To turn it on again, just bool the fricker - notice the second form of the call with another argument. Of course, like any game development in that situation, you have messy considerations like "when do I turn it on again" "What is the philosophical nature of when a new footfall begins" but that's no different at all in bullett, $$anonymous$$acPaint or whatever, you know - it will depend strictly on your situation of course and is often trivial.)

avatar image Fattie · Sep 09, 2013 at 11:09 AM 0
Share

"I come from AAA gamedev background..." dude what's this b/s man? :) Your headhunter's not on here ;-)

I always tell people I come form a "20 year" or "Blue label" background. As in $$anonymous$$acallan or Johnnie Walker

avatar image darbotron · Sep 09, 2013 at 11:09 AM 0
Share

As far as I can see in the docs, the only way to re-enable the collisions is to deactivate and then reactivate one of the objects (possibly both).

That sounds a bit nuts. Any idea how I might just deliberately un-ignore the collision?

avatar image Fattie · Sep 09, 2013 at 11:12 AM 0
Share

dude I hate that call but I think you just ,false at the end. Look at the second version of the call on the doco page. it's a state and you flip it...

alt text

screen shot 2013-09-09 at 13.12.08.png (11.1 kB)
Show more comments
avatar image
1

Answer by Ultroman · Nov 29, 2017 at 10:06 PM

This is not currently possible in Unity.


There are workarounds, but none let you handle the cases where an object collides with 2+ things in the same physics step, and needs to be affected in a custom way e.g. be stopped or moved or bounced using custom code.

/

If you save the velocity/angularVelocity/etc. from last FixedUpdate, you will have the data for the object before any of the collisions happened. OnCollisionEnter(2D) is properly called for both collisions (yay), BUT you don't have much info about what happened. You have the circumstances, like the collision normal, the separation/distance, contact point(s), but you don't have data for each object, like position and velocity/direction before and after the collision, or how far into the physics step the collision occurred.

/

Even if you did, you cannot simply roll back the object to the collision point, and do some custom bounce-code for each collision, because when you change the behaviour/result of the first collision/OnCollisionEnter(2D), then the data for the second collision/OnCollisionEnter(2D) call is made invalid.

/

To handle 2+ collisions in a single physics step, you only have two choices, really:

  • React to the first OnCollisionEnter(2D) call for each physics step, and do any further collision detection for this physics step manually...but you may have seen the problem with this...any other object in the scene will not have been rolled back to its previous position. You will have to roll back every object, and manually do incremental physics/collision detection updates. That's a LOT of code and a LOT of CPU cycles.

  • Turn down the Fixed Time Step variable, even though that only makes the problem less frequent.

That gets us down to 0 possibilities to fix this problem.

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
avatar image
0

Answer by Eric5h5 · Sep 09, 2013 at 12:58 AM

The workaround isn't that convoluted: always store the velocity/angular velocity/position from the previous physics frame, and after a collision, if it's not desired, just restore the velocity etc. so it continues on as if nothing had happened.

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 fherbst · Sep 09, 2013 at 01:03 AM 0
Share

This doesn't prevent OnCollision/OnTrigger events from happening which then requires at least some additional infrastructure.

avatar image Eric5h5 · Sep 09, 2013 at 01:12 AM 0
Share

Well, yeah, it doesn't prevent those events from happening, that's why it's a workaround. It does, however, have the effect of ignoring collisions on-demand, which is what you're asking for.

avatar image fherbst · Sep 09, 2013 at 01:15 AM 0
Share

I'm not the OP :). I was just adding to your answer what I thought is also worth considering.

avatar image Eric5h5 · Sep 09, 2013 at 01:19 AM 0
Share

Oops, sorry about that!

avatar image darbotron · Sep 09, 2013 at 09:19 AM 0
Share

This 'workaround' is barely even a workaround - it just puts the object back where it was on the frame before the collision which is not even vaguely the same thing that I am asking about.

By 'ignoring' the collision I mean preventing the physics solver from resolving the collision - i.e. the engine detects the collision with full physics info generated, but then allows me to ask it to behave as if the collision didn't happen which would let the objects pass through each other.

Obviously it is possible to ignore collisions using layers or Physics.IgnoreCollision, but these approaches are limited in that (as far as I can tell) they only allow either:

  1. no collisions, or

  2. all collisions

between any two specific objects.

The behaviour I am trying to achieve requires me to know when physically simulated objects have collided, look at the SPECIFIC circumstances of that collision (e.g. relative velocities, relative positions, the specific objects involved and their state (time since spawning for example) etc.) and then if, and only if, the circumstances meet specific conditions ask the physics simulation to ignore the collision.

Show more comments

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

21 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

Related Questions

How do I get the GameObject that is inside my Collision 1 Answer

OnCollisionExit2D workaround? 0 Answers

On Collision sound clip change 1 Answer

Destroy OTHER objects on Collision Unity 3 Answers

OnColliderEnter2D not working 2 Answers


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