- Home /
Multiple triggers on one object
I have an enemy and I want to have a few triggers on it:
Aggro radius (radius at which it comes to attack the player)
Retreat radius (radius at which it will forget about the player and return to base)
Attack radius (radius at which it will stop still and fire at the player)
From what I've read, objects can only have 1 trigger on, so I must create multiple game objects as children, then attach triggers to them, then make a short script which calls the parent script when it is triggered with both the type of trigger it's calling from, and the type of object that has triggered it.
Something like
// child
var parentScriptName : String; // parent script name
function OnTriggerEnter(collision : Collider)
{
var parent = transform.parent.gameObject.GetComponent(parentScriptName);
parent.OnTriggerEnterExternal(name,collision);
}
// parent
function OnTriggerEnterExternal (triggerName : string, collision : Collider )
{
... etc
Is this really the best way of doing this? I would have thought something as common as communicating with multiple triggers on one object would have something like this built in?
Answer by bwat6902 · Dec 08, 2015 at 11:56 AM
If the colliders don't themselves overlap (such as concentric spheres) you could check based on which trigger event occurs. For example, if you got an OnTriggerEnter, increase a counter. If you get OnTriggerEnter and the counter == 1, you know you have hit the first inner sphere.
Answer by asafsitner · Sep 26, 2011 at 08:59 PM
Unfortunately, Unity don't like it when there are two colliders on the same GameObject, and Triggers are essentially colliders and therefore a no-no.
However, you can use SendMessage
, which makes things much easier:
http://unity3d.com/support/documentation/ScriptReference/GameObject.SendMessage.html
Answer by feyyd · Jul 28, 2014 at 03:28 PM
Ran into this same problem, couldn't find much, but my solution was to just create a new gameObject, have it follow the object I wanted another trigger on, add an in-file class that contains the new trigger code. Made a skeleton that should be simple enough to modify.
using UnityEngine;
using System.Collections;
public class ProjectileDetectionStrippedForForum : MonoBehaviour
{
public float radius; //radius for collider
private GameObject hit_circle; //reference to the object containing CircleCollider2d thing
private CircleCollider2D c2d; //reference to the added circle collider
private CustomSecondTrigger pdtf; //reference to the in file class that contains trigger code for new trigger
void Start ()
{
//create and add components
hit_circle = new GameObject ();
c2d = hit_circle.AddComponent<CircleCollider2D> ();
pdtf = hit_circle.AddComponent<CustomSecondTrigger> ();
//if we need to reference this created gameobject from the created trigger class below, we need to have a reference
pdtf.Sendee = gameObject;
//setup our collider
c2d.isTrigger = true;
c2d.radius = radius;
c2d.center = transform.position;
}
void FixedUpdate() {
//follow the object this script is attached to
c2d.center = transform.position;
}
void Evade() {
//can call a function here from the trigger, or can run code in the next defined class that we attach to our GO
}
}
public class CustomSecondTrigger : MonoBehaviour
{
private GameObject sendee;
public GameObject Sendee {
get { return sendee; }
set { sendee = value; }
}
void OnTriggerEnter2D(Collider2D other) {
//can send message to whomever or run our code here
Sendee.SendMessage( "Evade" );
}
}
Answer by DaJuice · Nov 20, 2012 at 09:53 PM
I'm trying to figure out a way to overcome this, in my opinion, huge omission from Unity. The only thing I can think about is your solution, but here is my precise solution, which I'm still not totally satisfied with.
using UnityEngine;
using System.Collections;
public class ColliderContainer : MonoBehaviour {
public MonoBehaviour mediator;
private ICollidable _mediator;
void Awake () {
_mediator = (ICollidable)mediator;
}
void OnTriggerEnter(Collider other) {
_mediator.enterCollision(other, LayerMask.LayerToName(gameObject.layer));
}
}
This is the children script. mediator is the monobehaviour which has an enterCollision method that will handle the collisions, just put the script that will handle on top of the components list in your gameObject, then drag the gameObject in the monobehaviour slot (could make something more automatic, but it would be too heavy for what it is)
Yes I agree and the OnTriggerX vs OnCollisionX seems like a wierd distinction.
I think the API should be more like: - You could specify any number of collider which can each have different collider shapes. - When you attach a collider to a script, it will get OnTriggerX events for that collider. - You would need to attach the collider to a rigidbody's script in order for the physics code to know the collider for the object.
Answer by Kronas · Jun 21, 2013 at 03:12 PM
So I have been working on the same issue, and the best solution that I have found for this issue is just to create multiple cube objects to use as triggers and attach them to the character's prefab. Then use these triggers to call methods from within that character accordingly.
You shouldn't need to attach actual cubes, just empty gameobjects with colliders.
Your answer
Follow this Question
Related Questions
When collider enters trigger, colliders parent = triggers parent 1 Answer
Problems with the Trigger Collider (randomly fictional) 1 Answer
How to prevent a game object from colliding with its parent 2 Answers
Can't click gameobject when over another trigger? 1 Answer
Does OnTriggerStay ignore layers? 1 Answer