On TriggerEnter and Tag question.

hello there,

Have a few question to ask about trigger and tag. From the title above I know that you can check what gameObject are triggering the trigger by the tag that the game object have, example :

static var onHit : boolean;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
 		onHit = true;
	}
}

Okay, now for the question. Can I check if the player are triggering the right gameObject by tag. example:
this is some pseudo code that I think how it should be done, well not sure about it anyway.

static var onHit : boolean;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player"  objObject.tag == "P01")
	{
 		onHit = true;
	}
}

thanks in advance.

I did a nested if-else loop to check for two different object tags (the one that collided and the one that was collided). It works so I’m guessing that if you do ‘and’ in the if-loop, it should work.

Hi !. the second code is correct, you should only change the objObject.tag with gameObject.tag …

Thanks @wolfhunter777 and @Mig-081 for the quick answer, It does work.

But need to check something because right now when the player hit the gameObject it does detect the gameObject tag but it destroy all of the gameObject at once.example:

#pragma strict

public var objConfetti : GameObject;
public var objObject : GameObject;
public var objRotate : int;

static var onHit : boolean;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
		if (gameObject.tag == "P01")
		{
 			onHit = true;
 			print ("this is: " + objObject.tag);
 		}
 		else if (gameObject.tag == "P02")
 		{
 			onHit = true;
 			print ("this is: " + objObject.tag);
 		}
 		else if(gameObject.tag == "P03")
 		{
 			onHit = true;
 			print ("this is: " + objObject.tag);
 		}
 		else
 		{
 			onHit = false;
 		}
	}
}

function Update () 
{
	kill ();
}

function kill ()
{
	if (onHit == true)
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
	}
	else
	{
		transform.Rotate (Vector3.up * objRotate * Time.deltaTime);
	}
}

write a coroutine, just add a yield WaitForSeconds before destroying , Destroy class is really fast :wink:

@Mig-081, the Destroy part is fine, I like to Destroy stuff haha:)

The problem that i got is it destroy all the gameObject that are not spesific tag.Example, If i trigger tag “P01” it will also destroy all the other gameObject which is tag “P02” and P03".

From what I’m seeing, if the player collides with objObject (which the script is attached to), you want to destroy that game object yes? From what I did in C#, I used Destroy(this.gameObject).

Got it, I change my code to this:

//Hizral Ashraq 
//14/11/2011, Monday, 4.20PM
//Manager the actor triggering the object.
#pragma strict

public var objConfetti : GameObject;
public var objObject : GameObject;
public var objRotate : int;

static var onHit : boolean;
static var onHit2 : boolean;
static var onHit3 : boolean;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
		if (gameObject.tag == "P01")
		{
 			onHit = true;
 			print ("this is: " + objObject.tag);
 		}
 		else if (gameObject.tag == "P02")
 		{
 			onHit2 = true;
 			print ("this is: " + objObject.tag);
 		}
 		else if(gameObject.tag == "P03")
 		{
 			onHit3 = true;
 			print ("this is: " + objObject.tag);
 		}
 		else
 		{
 			onHit = false;
 		}
	}
}

function Update () 
{
	kill ();
}

function kill ()
{
	if (onHit == true  gameObject.tag == "P01")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
	}
	else if (onHit2 == true  gameObject.tag == "P02")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
	}
	else if (onHit3 == true  gameObject.tag == "P03")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
	}
	else
	{
		transform.Rotate (Vector3.up * objRotate * Time.deltaTime);
	}
}

Did not know about this. thanks will try and give the feedback.

So I manage to do what I wanted to do, but got this problem. Here a video to show you what my problem is

As you can see in the video, the red box destroy incorectly. It supposed to be destroy individualy when player hit them.

here’s my script:
This script I put in all the red box. They share the same script.

#pragma strict

public var objConfetti : Transform;
public var objObject : GameObject;
public var objRotate : int;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
		if (objObject.tag == "P01")
		{
 			ManagerPowerUp.onHit = true;
 			print ("this is: " + objObject.tag);
 		}
 		else
 		{
 			ManagerPowerUp.onHit = false;
 		}
	}
}

function Update () 
{
	kill ();
}

function kill ()
{
	if (ManagerPowerUp.onHit == true  gameObject.tag == "P01")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
		ManagerPowerUp.onHit = false;
	}
	else
	{
		transform.Rotate (Vector3.up * objRotate * Time.deltaTime);
	}
}

How about you change the script so that the script is attached to the player. When the player collides with the collided object, you destroy the collided object.

C#

void OnTriggerEnter(Collider obj)
{
	if(this.gameObject.tag == "Player")
	{
		if(obj.tag == "P01")
		{
			Destroy(obj);
		}
	}
}

Another way to go about it is to do it from the obstacle. Since the script is going to be attached to all the objects to be destroyed, you just have to destroy that object.

C#

    void OnTriggerEnter(Collider obj)
    {
        if (obj.tag == "Player")
        {
            Destroy(this.gameObject);
        }

    }

The code above will work only if the script is attached to all the objects to be destroyed by the player.

There’s some messed up stuff going on there, OnTriggerEnter only fires on the object that was collided with. Your issue is you are using the class variable ManagerPowerUp.onHit. A class variable is the same for every instance of the class.

There’s no need to check the tag of the object unless you want to use one piece of code to handle several different classes of objects (and tags is still a bad solution to this).

You could make the onHit variable a private variable and refer to it in your code as onHit (without the ManagedPowerUp bit in front). However there’s likely no need to call the kill function in update. Just call it from the collision.

So remove your update method, and change OnTriggerEnter to:

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
           kill();
        }
}

Sorry @JohnnyA and @wolfhunter777, I think I misled you guys, I cut some part of my script just to show you the main script for the red box.

this is my full script for the ObjTrigger.js and the ManagerPowerUp.js:

The “ObjTrigger.js” script I put it inside all my trigged object, tag “P01” : Red Box, “P02” : Blue Box and “P03” : Clock.

#pragma strict

public var objConfetti : Transform;
public var objObject : GameObject;
public var objRotate : int;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
		if (objObject.tag == "P01")					
		{
 			ManagerPowerUp.onHit = true;
 			print ("this is: " + objObject.tag);
 		}
 		else if (objObject.tag == "P02")
 		{
 			ManagerPowerUp.onHit2 = true;
 			print ("this is: " + objObject.tag);
 		}
 		else if(objObject.tag == "P03")
 		{
 			ManagerPowerUp.onHit3 = true;
 			print ("this is: " + objObject.tag);
 		}
 		else
 		{
 			ManagerPowerUp.onHit = false;
 			ManagerPowerUp.onHit2 = false;
 			ManagerPowerUp.onHit3 = false;
 		}
	}
}

function Update () 
{
	kill ();
}

function kill ()
{
	if (ManagerPowerUp.onHit == true  gameObject.tag == "P01")		
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
		ManagerPowerUp.onHit = false;
	}
	else if (ManagerPowerUp.onHit2 == true  gameObject.tag == "P02")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
		ManagerPowerUp.onHit2 = false;
	}
	else if (ManagerPowerUp.onHit3 == true  gameObject.tag == "P03")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (objObject);
		ManagerPowerUp.onHit3 = false;
	}
	else
	{
		transform.Rotate (Vector3.up * objRotate * Time.deltaTime);
	}
}

The 'ManagerPowerUp.jg:" I put it inside an empty gameObject and rename it as GameManager

#pragma strict

public var objPlayer : GameObject;

static var onHit : boolean;
static var onHit2 : boolean;
static var onHit3 : boolean;

function Update () 
{
	MainPick ();
	Ice ();
}

function MainPick ()
{
	if (onHit)
	{
		ScorePoint.pickCounter += 1;
		ScorePoint.score += 10;
	}
}

function Ice ()
{
	if (onHit2)
	{
		objPlayer.GetComponent.<ControllerPlayer>().moveSpeed = 0;
		yield WaitForSeconds (3);
		objPlayer.GetComponent.<ControllerPlayer>().moveSpeed = 60;	
	}
}

Yes there will be several different classes of object. What other solution then tag.

Have you tried our suggestions? Also, if the script is going to be attached to the objects, why must you pass the object that the script is attached to into the script? Can’t you use this.gameObject? But then again, I have only coded in C# so I don’t know how Javascript works.

Yup tried it and it does work, I did used the way you suggested before I change my script to this. just wanted to learn different type of scripting structure. I forgot to change the “objObject” to “gameObject” sorry about that.

yeah, just double check, just like wolfhunter777 said
//check is it picked up by player
if (hit.gameObject.tag == “Player”)
{
if (target.gameObject.tag == “Player”)
{
Destroy(gameObject);

//add health to the player
PlayerGUI eh = (PlayerGUI)target.GetComponent(“PlayerGUI”);
eh.adjustHealth(100);
//add mana to the player
eh.adjustMana(100);
}
}

yeah, just double check, just like wolfhunter777 said
//check is it picked up by player
if (hit.gameObject.tag == “Player”)
{
if (target.gameObject.tag == “Player”)
{
Destroy(gameObject);

//add health to the player
PlayerGUI eh = (PlayerGUI)target.GetComponent(“PlayerGUI”);
eh.adjustHealth(100);
//add mana to the player
eh.adjustMana(100);
}
}

I guess not a big issue on desktop but tags are quite slow. They also use string based comparison so can lead to coding error.

Without any detailed knowledge of exactly what you are doing I’d suggest an enum and an instance variable on the script.

EDIT: The alternative to using tags is for example to use layer based collision… if you only care about a player touching an object then you can set the physics engine to only trigger collisions between players and the object.

Thank @wolfhunter777, @JohnnyA and @Mark Lui for the pointer.

I manage to solved it. Change a bit of my script. Now it work. Here’s what I did:

The new “objTrigger.js”

#pragma strict

public var objConfetti : Transform;
public var objObject : GameObject;
public var objRotate : int;

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
		if (objObject.tag == "P01")					
		{
 			ManagerPowerUp.onHit = true;
 			kill ();
 			print ("this is: " + objObject.tag);
 		}
 		else if (objObject.tag == "P02")
 		{
 			ManagerPowerUp.onHit2 = true;
 			kill ();
 			print ("this is: " + objObject.tag);
 		}
 		else if(objObject.tag == "P03")
 		{
 			ManagerPowerUp.onHit3 = true;
 			kill ();
 			print ("this is: " + objObject.tag);
 		}
	}
}

function kill ()
{
	if (ManagerPowerUp.onHit == true  gameObject.tag == "P01")		
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (gameObject);
	}
	else if (ManagerPowerUp.onHit2 == true  gameObject.tag == "P02")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (gameObject);
	}
	else if (ManagerPowerUp.onHit3 == true  gameObject.tag == "P03")
	{
		Instantiate (objConfetti, transform.position, transform.rotation);
		Destroy (gameObject);
	}
	else
	{
		transform.Rotate (Vector3.up * objRotate * Time.deltaTime);
	}
}

The new “ManagerPowerUp.js”

#pragma strict

public var objPlayer : GameObject;

public var pauseWatch : int = 0;

static var onHit : boolean;
static var onHit2 : boolean;
static var onHit3 : boolean;

function Update () 
{
	MainPick ();
	Ice ();
	StopTime ();
}

function MainPick ()
{
	if (onHit)
	{
		onHit = false;
		ScorePoint.pickCounter += 1;
		ScorePoint.score += 10;
	}
}

function Ice ()
{
	if (onHit2)
	{
		onHit2 = false;
		objPlayer.GetComponent.<ControllerPlayer>().moveSpeed = 0;
		yield WaitForSeconds (3);
		objPlayer.GetComponent.<ControllerPlayer>().moveSpeed = 60;	
	}
}

function StopTime ()
{
	if (onHit3)
	{
		onHit3 = false;
		GetComponent.<Timer>().watchDelay = 0;
		yield WaitForSeconds (pauseWatch);
		GetComponent.<Timer>().watchDelay = 1;
	}
}

I think you are still missing the point about class variables, thats a terrible way to manage things, every time you add a new object you will need to add a new variable.

It much easier (and more efficient) to call a function on the manager object than to set a flag and check for it in update.

Try removing update code for your manager and doing something like:

public var objConfetti : Transform;
public var objObject : GameObject;
public var objRotate : int;
[b]public var powerUpManager: ManagerPowerUp;[/b]

function OnTriggerEnter (hit : Collider)
{
	if (hit.gameObject.tag == "Player")
	{
		if (objObject.tag == "P01")					
		{
 			kill ();
                        [b]powerUpManager.MainPick();[/b]
 		}
 		else if (objObject.tag == "P02")
 		{
 			kill ();
                        powerUpManager.Ice();
 		} 
                else if(objObject.tag == "P03")
 		{
 			kill ();
                        powerUpManager.StopTime();
 		}
	}
}

EDIT: Dont forget to link your power ups to the power manager in the editor.