- Home /
Double Colider trigger
Hello there, I am wondering how you would go about having a trigger that is only set off when BOTH colider are touched. Ex: you have two game objects, and two coliders. When each of the game objects hit both coliders, it will then trigger a hidden game object. I do not want any objects or coliders getting destroyed. I want the user to be able to do this as many times as he wants.
Answer by AaronWinterhoff · Feb 03, 2014 at 01:56 PM
Hey, the reason you're having an issue with BlackWingsAnswer is because you're using OnTriggerStay twice. You can only have one collider on a game object.
What you need is a script called Detector - which you place on two different gameobjects with colliders on them. Make sure you tick the collider to be a 'trigger' (little checkbox in the collider option).
Then, I've created a gamelogic script, attach it to a blank gameobject, as you can see, you make a reference to each Detector in the logic, and it asks for two detectors - these are our gameobjects with a collider on them.
You drag both of those Detector objects in the two detector slots on the gamelogic script, and the gamelogic questions each trigger. When both of them are active, you can do something.
public class Detector : MonoBehaviour {
public bool entered = false;
public void OnTriggerEnter ( Collider _collider ) {
entered = true;
}
public void OnTriggerExit ( Collider _collider ) {
entered = false;
}
}
public class GameLogic : MonoBehaviour {
// References to your detector objects
public Detector detector1;
public Detector detector2;
public void Update () {
if ( detector1.entered && detector2.entered ) {
Debug.Log ( "Something is in both triggers" );
}
}
}
Those two errors that you're getting, here's what they are, btw:
Instantiate(hidden, transform.position, transform.rotation) as GameObject.
When you call Instantiate, you're telling Unity, 'I want you to spawn the Object hidden, at this position, as this rotation' (I don't know what the hidden object type is). This is fine, Unity will do it. Unity doesn't much care what the object is, it'll spawn it. If it has a gameObject attached (which it will), then it'll be there. In this case, you just remove 'as GameObject'.
To explain why however, when you use the 'as GameObject' at the end, you're trying to tell Unity that you want to assign a reference of the spawned object to a variable. If you don't have a variable to assign to, it gives an error. If you had
// Instantiating an object without storing a reference
Instantiate ( hidden, transform.position, transform.rotation );
// Storing a reference to the Object, 'as GameObject'
GameObject someObject = Instantiate ( hidden, transform.position, transform.rotation ) as GameObject;
// Now we have stored someObject in memory if we want to destroy it later from code, or change its colour, etc.
When you give the 'as GameObject', you're saying which script on the thing you're instantiating you want to reference.
OnTriggerStay(UnityEngine.Collider)
That's why we need separate scripts for each collider object. They can't be the same, because Unity only allows one call to OnTriggerStay (). That's why Unity is saying that it is 'already defined'.
Dude that was the most solid answer I've ever received on this website! Thank you! it works excellent. You need to write "C# for unity" tutorials :P I actually understood it. Which is something myself and others apparently find hard to come across, relate-able topics with backed up answers and explanation. Alot of books seem to tell you how to do things, but it doesn't tell you why you would want too
Here is a random question, I was re-reading your info, I copy and pasted it into a notepad for keeping. You said a game object can only have one collider. Does that mean, can not have two colliders of the same type? Or would I be able to give a game object both, sphere collider, and also a box collider? Would that work in a situation? Lord knows I'll find a weird reason for something like that
Thanks very much :), I’m really happy that it came across clearly and helped. I have quite an interest in how to simplify and $$anonymous$$ch program$$anonymous$$g in understandable ways; I've worked with a number of university tutors recently, trying to see if we can $$anonymous$$ch game program$$anonymous$$g with a bit of computer science behind it, it’s a really interesting space. I feel that the ‘why’ you’re doing something is actually the most important part of an answer.
In regards to your collider question – no you can’t have more than one collider object on an individual gameObject. I’ll explain why below, feel free to read to whatever level you need.
The simple explanation is program$$anonymous$$g based – because Unity's design really encourages a component–based architecture, their built in functions and methods are set up in a particular way to encourage you to build with lots of little simple components.
This is why we had to have our two different objects with Colliders and separate scripts on them. As you can see, once you start to get that workflow with the program, you build your game out of lots of little gameObjects with scripts on them, ins$$anonymous$$d of one big class that tries to handle everything.
However, only being able to have one collider on a gameobject is ok though, great even. If it’s just static geometry (doesn’t move, like environment for instance), you have multiple gameObjects with their own individual colliders on them, arrange them into the overall collider shape that you need. Then drag each of the collider gameObjects underneath an empty one (can be done with Create > Empty GameObject), so that they’re parented to it. It’ll act exactly the same way as if you had them all on the one gameobject, but is easier to control, because you can move each separately, or move them all by grabbing the parent.
If you want to use rigidbodies with colliders in this manner (say for a character), there’s one additional step. Let’s pretend the Capsule Collider doesn’t exist for a $$anonymous$$ute. Say you want to use multiple colliders for something, say it’s a very basic capsule shape with a sphere on each end, and box in the centre. O = O This kind of shape.
We can create a number of colliders separately. Two spheres and a box, rigidbodies on each. We then parent them all under an empty gameObject again, so that they all move together when we move the parent. To stop these rigidbodies falling away from each other, we put two fixedJoints on the box in the centre, and drag the two sphere colliders onto the fixed joints on the box, and make the joint break strength infinite. All the rigidbodies will move together, and retain the positions relative to each other that you’ve given them.
Once again very resourceful info, I seriously appreciate it. It was all pretty clear to me. Your example was similar to what I am doing honestly so I understood the reference. Thanks for clearing up the collider questions! It's also fantastic you are considering writing tuts. They are surely needed, the "why you need to do soemthing" really does seem to lack clear reasoning for beginners. Do you recommend anything at all for learning C# for unity? Strangely I can look at a script, tell you right away if its java or c# and I can recycle scripts together, but I feel that's bad practice not knowing exactly why it's written how it is. For some reason I never know how to start writing. I'm not confident in what does what.
No problem :). By the look of it, I'm not sure how new this is, but you can do multiple colliders all on the one gameObject, I wouldn't recommend it though, especially if you want to have any code associated with them.
Unity answers says to point you to the link below, rather than repeat something that has been said before (there are a zillion tutorials at the link):
http://answers.unity3d.com/questions/12321/how-can-i-start-learning-unity-fast-list-of-tutori.html.
This might better be answered in a question already made on UA, I'm trying to learn all the commenting procedures and rules.
The quick advice I can give you is that in my opinion, there are three elements to program$$anonymous$$g - syntax, computer science, and paradigms. Syntax are the languages, and have similarities between the different languages, and differences. Regardless however, programs always talk to the computer in similar ways at a low level.
Paradigms are the actual thinking behind why you're coding something a certain way, and this is the 'never know how to start writing' problem. The best way to learn these things, is to see what better programmers have done to deal with a certain situation, and try to do do what they've done, but by yourself. Type the code in manually, and break down how it works. That way you get double the benefit, you learn to read and understand the 'why' (important when you're working in a $$anonymous$$m), and you learn methodologies and design patterns for your own coding.
Computer Science is the easel that you're painting on - the computer itself. As you get better at program$$anonymous$$g , if you understand what your code is actually doing on a fundamental level, then at makes it so much easier to debug. Code by Charles Petzold is a great introduction into the world of computers themselves.
And have nice coding conventions. If you learn to write your code like the pros do, you'll be able to understand the logic flow and read your own work easier. id's a pretty good starting place.
ftp://ftp.idsoftware.com/idstuff/doom3/source/CodeStyleConventions.doc
Also, you can accept the answer as correct if you're happy with it (I believe Unity answers allows that).
Answer by BlackWingsCorp · Feb 03, 2014 at 09:41 AM
It's pretty simple actually here's a little example: public GameObject obj1; public GameObject obj2; public bool isin1; public bool isin2; public GameObject hidden;
void Update(){
if(isin1 == "true" && isin2 == "true"){
Instantiate(hidden, transform.position, transform.rotation) as GameObject
}
}
void OnTriggerStay(Collider hit1){
if(hit1.gameObject.name == "obj1"){
isin1 = true;
}
}
void OnTriggerStay(Collider hit2){
if(hit2.gameObject.name == "obj2"){
isin2 = true;
}
}
error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
referering to
Instantiate(hidden, transform.position, transform.rotation) as GameObject
This one as well
OnTriggerStay(UnityEngine.Collider)' is already defined. Rename this member or use different parameter types
18,12): error CS0019: Operator ==' cannot be applied to operands of type bool' and `string'
Answer by fafase · Feb 03, 2014 at 02:06 PM
So hold on, two objects, two triggers and one instantiation when both objects are each in one of the colliders.
Ok, create an empty game object then create two other game object with trigger collider. Make them children of the empty one.
public class ChildrenObject:MonoBehaviour
{
public bool isFirst;
public MainObject script;
void OnTriggerEnter()
{
if(isFirst)script.First = true;
else script.Second = true;
}
void OnTriggerExit()
{
if(isFirst)script.First = false;
else script.Second = false;
}
}
on the main object:
public class MainObject : MonoBehaviour
{
private bool first;
private bool second;
public GameObject obj;
public bool First
{
get{return first;}
set{first = value;
if(first && second)Instantiate(obj);
first = second = false;
}
}
public bool Second
{
get{return second;}
set{first = value;
if(first && second)Instantiate(obj);
}
}
}
So, the first script goes on the two object with trigger. All you need is to drag the main object into the script variable, then tick one with isFirst.
Place the second script into the parent object. Drag the object you want to create in the obj slot.
I guess that should do it.
Great answer man, I have not actually tried this script out yet, I have found a similar solution above. BUT, never the less I like building a collection of scripts to future use. I'm going to add this to that pile, hopefully I'll check it out tonight when I get home. Thanks for the input!
Your answer