I have 2 layers i want to arrange correctly these are:
Player
DoorTrigger
I want the OnTriggerEnter function of the DoorTrigger layer to trigger when Player enters its trigger collider. But i do NOT want the OnTriggerEnter function on the Player to fire when the player enters the door trigger collider.
Currently the door detects the player as it should and all that works fine, the problem is the player is also detecting the door collider and is setting off it’s own function when it should ignore it.
Is it even possible to setup a one way trigger collision ruleset in that way?
Collisions/triggers are not directional; they involve a mutual contact between two colliders so no, there’s no direction possible because one didn’t move into the other, they could both be moving.
You are provided the colliders in question so your script logic should be able to handle this appropriately.
Ah i guess that makes sense. Shame we can’t add that support by using a 2D collision matrix - in my situation it would reduce the trigger functions being called by 50% on the hot path which would add a nice performance boost
If you’re requesting a feature to be considered in the future, could you explain how would it work? As I said, collisions are not directional so what are the rules here to where collision/trigger messages should be sent.
They’re actually super lightweight. It’s the code that runs in them that dominates by many orders of magnitude.
Suppose you have a player that has a trigger collider to detect nearby enemies, and a door which has a trigger collider so it can open when the player is near by.
If you have a collision matrix that has player and door marked since you need the door to trigger when the player is nearby this fires both of their triggers off.
Now for directional triggers where you only want one to trigger the other you could have directional triggers written like this in the editor:
Door ↔ Player
If you tick door, the door triggers when player passes by, if only the player is ticked then only player is triggered, or if both are ticked (which should be default) then both are triggered.
In this case there is no reason for a player to be triggered by a generally static object (not including its animation) like a door so it makes sense for only the door to be triggered by the player.
You’re right that it is pretty light weight even if both trigger, but it just makes code robust and cleaner.
As a player i only care about if an enemy hits my trigger but not a door, so with directional triggers i know for 100% certainty if a player trigger gets activated it must be an enemy because door cannot trigger the player with directional triggers.
In the end, there is no direction to any contact so to be clear, I wasn’t asking how the UI would look or what you’d check but more of what are the rules that this new feature uses to determine what to report to what. It has to be a solid, well defined rule and it’s not super clear what you are asking for. Saying A to be triggered by B isn’t really defining the feature or maybe it’s the language is muddying the feature; in the end a non-directional contact occurs in the physics engine and Unity then broadcasts that to the parties involved.
It looks like above you are (maybe) simply asking to be able to control which object gets a callback (Collision or Trigger) in that layer interaction so no rules beyond that? This would apply though to all objects in that layer/layer interaction making the choice a quad-state choice. Nothing or Layer A+B or Layer A Only or Layer B Only.
NOTE: I hope I’m not sounding pedantic here, it’s just that a feature cannot be vaguely defined.
I am not sure I fully understand what you mean by “what are the rules of this new feature to determine what to report to what”.
Is it not up the developer to choose the rules? We already choose what reports to what with the collision matrix. Except currently we cannot discriminate which layer triggers which layer more specifically, so they both simply trigger each other.
With an extra check could it not simply check if we permit A to trigger B (and if so broadcast to B) and B to trigger A (then broadcast to A), and of course both if we permit both ? This removes the need to always do “otherCollider.GetComponent() != null etc” every time the trigger is fired because I will know with certainty based on the rules i set what can trigger it.
When i say A and B i refer to the layers in unity.
Of course but I am talking about you describing the rules which the feature needs to follow.
They don’t “trigger each other”. The matrix simply allows or disallows contacts between them. A callback doesn’t indicate A “triggered” B. That’s a scenario in your mind, not what the engine is seeing and it’s the engine that needs to know what to do here.
So is that what I suggested here… ?
Let’s stop saying “triggering” please. Two things come into contact, this is what the matrix controls ONLY. Whether you get a OnTrigger or OnCollision isn’t related. You’re (seemingly) talking about callbacks only and I need to make sure that is indeed what you mean.
So in short, you’d like to be able to say, “Hey Unity, only send callbacks to Layer B here, thanks” ?
EDIT: This would be a very useful feature for a few use-cases I’ve seen come up recently and actually overlaps some 2D physics work going on for performance i.e. reducing overhead of callbacks that the dev is simply not interested in.
Yes, so just to confirm that a feature like this is something we’re looking at adding anyway as long as there is a clear understanding that it’ll only send to exactly the layer you request.
One of the issues though is the existing Layer Collision Matrix; right now it’s a simple on/off selection. Changing that to be four modes would potentially be annoying for those who only want on/off. Something else being considered is whether doing this at a global level is actually too high a level. If we were to add the ability to select on a per Collider2D or per Rigidbody2D (applies to all attached Collider2D) which layers you’re interested in seeing callbacks for then that would have the advantage that it’s much more fine-grained and we don’t have to modify the existing Layer Collision Matrix.
Also this way, you could select Trigger/Collision independantly so for instance you could indiate that you’re interested in all OnCollision callbacks (maybe on specific layers) but no OnTrigger callbacks.
If you have any further thoughts on that then I’m certainly interested in hearing them.
The new contact modification API is higher performance with pretty much raw results from Physx, right? This allows the developer to not use OnCollision or OnTrigger at all (at least I replaced it with the contact mod callbacks for control and speed).
Yes, that’s an option to use for sure and that’s coming to 2D too however it’s also not ideal for a lot of devs, especially new or inexperience ones. Also, the callback handling code happens regardless so there’s still overhead in there too which, if you’re ignoring them and using the contact-mod feature, you’d probably like to remove too.
The overhead for 2D physics for callbacks is much higher than it is for 3D physics though simply because of how awkward it is to deal with contacts in Box2D.
Weirdly, less code to write with this contact mod stuff. Less predictive prep and post sim patchup. As you say though it needs a more experienced developer.
My idea is to simply change the check boxes in the collision matrix to have 4 toggle states depicted as arrows:
So the default state is double arrows, click once and it will be an arrow pointing up (the first one in the image above), click a second time and it will be an arrow pointing left (the bottom example), and if you click a fourth time then there are no arrows at all since that declares those two layers do not contact each other. It just cycles through those 4 states.
So instead of tick or no tick, its double arrow, up arrow, left arrow or no arrows.
As long as one arrow exists the contact detection is same as the collision matrix has now, the arrows merely then depict what gets the callbacks after that point.
This means the collision matrix is unchanged you just merely add a bit more info to the tick box UI. I feel it will be pretty easy to understand by the arrows the direction the callbacks will be.
It won’t even change much the size of the collision matrix, though you might need slightly bigger check boxes so you can see the arrows in more detail. Other than that it will be familiar to what people are already used to using.
For less annoyance, right click can toggle between double arrow and no arrow to avoid having to click through all 4 states just to turn it off.
Yes, that was one of the design thoughts already but it doesn’t mean it’s “unchanged” and you’ll have to trust me on this, this would potentially cause a LOT of confusion. Not only that, what you’re asking for isn’t used that often as a workflow alone but we’re considering it because it helps with optimization too.
Well one way to make it less confusing is when a user mouse overs the toggle boxes it will give a full description tooltip of what layer will get callbacks based on the setup, so the user can just click again to change it until its what the user wants it to be.
The alternative (and i don’t like this particular alternative) is users manually add layer pair filters to a list as a relationship below the collision matrix you can only add a filter of a layer pair to the list if and only if the collision matrix has the two layers toggled on. So something like this:
But in my opinion - this could be tedious with a long list of layers in larger projects and its far less compact.
I feel this has other problems too, like if I turn off the collision matrix toggle does it auto remove the filter too etc.
The one plus side on this, is since the user has to manually add the argument they are far less likely to be confused by the behaviour that occurs because they actively set the argument.
Yes, your points above have already been considered for making it global only. Nothing has been set in stone yet and we’ll have to go through the whole design and UX/UI review too. There’s arguments for global in settings and for per-object too and there’s potentially a compromise. Also other factors I’ve not stated such as moving away from using Layers as the primary mechanism for controlling interactions in physics because of their limitations.
Nothing you’ve said above is wrong. It’s all a consideration and I appreciate the time you’ve taken explaining it too.