OnTrigger Enter, Exit ...

Hello! I have hard times with Triggers in Unity, I came from Unreal in order to learn to script in C# , and Unity API looks more friendly than Unreal API and c++. And I’m very happy with my progress( I have no experience as traditional programmer, but I do stuff in blueprints in Unreal and I have an understanding about this kind of work, it’s not so hard to translate in c# what I had learned from blueprints). The problem is that right now I think that Unity System triggering it’s wrong, or is a bug or something.I use Unity 2018.2.0f2, in Unreal each trigger collider have it’s own fire event when TriggerEnter, TriggerExit so you can have multiples triggers and each one is treated as distinct and fire just for itself and execute specific code. In Unity you can’t target a specific trigger. If are multiples triggers on the same game object and just one is touched , others triggers fires as well. What the… is this behavoir?It’s an absolute mess. In my Unity scene I have an Player object , an AI bot. The Player execute it’s own specific code on his TriggerEnter, and the AI bot execute it’s own specific code on his TriggerEnter(this is my intention), but a fire in TriggerEnter AI bot causes a fire as well in TriggerEnter Player which is 10 m away from the AI bot, so never touches each other, and the Player not touch somethingelse(this two entities are not child-parent).It seems that if a game object activate his own TriggerEnter, other game objects activate as well their TriggerEnter in the same time, which is a stupid, uselles behavoir. I like Unity but this thing is absolute horrible and I can’t do what I intent without ability to say, target this triggerA and when get touched do 777777, and target this triggerB and when get touched do 999999999.(triggers are on the same object), and when this triggers fires on objectA , the same triggers(by name) must not fire on the others game objects without any sense. So what is this?

One single biiiiig paragraph!! :wink:

So let me just check if I understand you correctly. You are saying that if, for example, the player hits AI_Bot1 and the OnTriggerEnter is called on AI_Bot1, then OnTriggerEnter is also being called on AI_Bot2? And AI_Bot2 is some distance away and has not collided with the player?

First thing is, if that is a correct understanding, that is not the way Unity works. So the next thing is to try and split out what has actually happened.

So, for example, create yourself a new blank scene. Populate it with the player and AI_Bot1 and AI_Bot2 (all nicely spaced apart from each other). Now get the player to run into AI_Bot1. You should notice that AI_Bot2 is not affected. Or do you see AI_Bot2 affected even in this simple scenario?

When the player triggerEnter something or the Ai bot triggerEnter something, this events are fired in both scripts, not just in the script of the object that actualy touch something.(The player touch nothing, i check this very carefully in isolation, but his event fire as well when Ai bot event fire.)

Ok, so how about giving this a try (I have just done this and it works as expected) :

  • Create a new scene.
  • Add a cube (name it “Alfie”).
  • To Alfie, add a Box Collider and mark it as Trigger.
  • To Alfie, now add the script below.
  • Duplicate Alfie twice - name them Bruce and Clara.
  • Spread them out slightly along one axis with Alfie in the middle.
  • To Alfie add a RigidBody - mark it as kinematic.
  • At this point, we have only 3 simple objects: each with one script and default shaped colliders. Plus one RigidBody.
  • Now play the scene in the editor.
  • At this point, in the console, the 3 cubes will announce themselves.
  • Now, in the Editor window, drag Alfie into Bruce. Both Alfie and Bruce will announce their hit with each other but nothing from Clara.
  • Then move Alfie into Clara. Both Alfie and Clara announce but nothing from Bruce this time.
  • So now, you can slowly start adding things from your real objects into these simple cubes to see at what point the problem appears.
public class Test : MonoBehaviour
{
    void Start()
    {
        Debug.Log("My name is: " + name);
    }

    void OnTriggerEnter(Collider other)
    {
        Debug.Log("I am " + name + " and I have hit " + other.name);
    }
}

I did your test and the results are:
When Clara or Bruce hit Alfie the message is printed correct, but when Clara hit Bruce, the hit is not register, so no message and as well when Bruce hit Clara, no hit,no message. This is likely because Bruce or Clara have not a rigid body attached.

So your test proves that Unity is correct and not fire the same event in another object without a logic reason. But in my case the problem is a little bit more complex and It’s happens. I have multiples rigid body attaches to different objects and some parenting. I will post on youtube a video with the proof. I will post the link

Yes, that is exactly correct.

I don’t doubt you. :slight_smile: All I am trying is to help find out what is different between the test we have just done and the situation you have with your current setup.

Like I said, see if you can start copying things in from your real code to find out at what point Alfi, Bruce and Clara start going wrong.

Hello! I reproduce the issue in a minimal way and I attached the project file.
I still can not figure out what’s going on. Maybe you can take a look.
The setup is exactly the same in my original scene. So if Bruce hit Alfie trigger box, All triggersEnter in all scripts fires in the same time , which is not what I want. I expect just the Alfie child ConeOfVision TriggerEnter to fire but that does not happen.
Thanks in advance.
I’m on the PC Windows.

3581446–289583–TriggersProblem.rar (3.84 MB)

So just remove onTriggerEnter from everything other than alfie. I’m getting expected behaviour with your project.

trikk the nikk

I can’t do that because others triggers
have their role, functionality in original scene. I need them.

Just set some ignores, then. You can get the name of other collider and ignore it if its gameObject is named Alfie.

BruceScript:

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

public class BruceScript : MonoBehaviour {

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.name == "Alfie") return;
        print("In BruceScript Enter");
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.gameObject.name == "Alfie") return;
        print("In BruceScript Exit");

    }
}

So I debug more and practically what happens is this:
If you put on an GAME OBJECT X, two colliders components A, B , and one of them is set as trigger(A) and the other one is not a trigger(B), well get ready for a shock. Unity activate OnTriggerEnter IN GAME OBJECT X, even when collider B(which is not a trigger) hit another trigger colider in the scene. Is this logic? Of course not! The user expects that OnTriggerEnter to be activated only when collider(A) which is a trigger, hit the other trigger in the scene.

yeah:

Collision in Unity can be tricky with all of the different types of colliders and collision handling functions. Here is a useful reference page that has some more details:

This is the desired behaviour, unless I’ve misunderstood the scenario… Basically, all objects involved into collision or a trigger events are able to process this particular event (as described in the documentation linked in the previous post and the table which can be found there).
You can even remove the collider which is marked as trigger from object X, only leaving the normal collider on it and some script that defines the OnTriggerXYZ messages. It’ll also react when you enter another trigger.

Suppose you have a door and a player. Simple setup, the player has a collider (and rigidbody), the door has a trigger area. If the player enters the trigger area, both should be able to react to it. There’s no reason why the player needs an additional collider that is marked as trigger.

That would not only cause additional overhead for the physics engine.
It would even have potential to cause additional trigger messages that you have to handle, as the player’s own collider would at least enter the trigger once if both overlap (unless ignored via physics layers).

Perhaps Unreal and Unity differ in this specific case, and I might be too biased since I almost exclusively use Unity, but it does actually make a lot of sense. If there is actually a difference, it doesn’t necessarily mean Unity is wrong about it, neither is Unreal.

Yes.

Okay, well , the things are a little bit different, I was accustomed in a specific way to see how multiple triggers work toghter, Unreal treats them in a distinct, isolated way, each one have their own Enter, Exit event which get activated only when that trigger surface touch something or is touched. This isolated mode allows accurate targeting. You know exactly which trigger touch something and what code you want to execute for that trigger.

Anyway, I don’t want to bore you talking about Unreal, I want to thank you all for your answers, Suddoha explained
fairly well how Unity behaves, now I understand , makes sense, it’s not something unbearable, and

I was able to solve my problem using a filtering approach inside OnTrigger… by tags with if, if else, as FMark92 suggested to me.

This is exactly what your provided example is doing.