Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Corberius · Oct 23, 2015 at 04:26 AM · 2d gamecollider2dnewbie

OnTriggerEnter2D gets executed repeatedly by each collided object with the same Tag

I'm trying to increase a variable (deaths) when the player collides with a wall (or "enemy"). For save time counting square spaces for the player, I duplicate the wall prefab (I don't know if It's bad, but I don't get bad performance) . The problem is when the player collides between two walls objects, the code gets executed two times, counting two deaths:

 function OnTriggerEnter2D(coll : Collider2D){
     var respawn = GameObject.Find("respawn");
     
     if (coll.gameObject.tag == "enemy"){
         deaths += 1;
         transform.position = Vector2(respawn.transform.position.x, respawn.transform.position.y);
     }
 }

Here is the example:

alt text

I don't know if I'm doing something wrong, the player have the "Is Trigger" and the wall not, the wall prefab and the enemy prefab (moving squares) have the "enemy" tag.

example.png (6.4 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by seth_slax · Oct 23, 2015 at 04:36 AM

I'm not entirely sure, but it could be that the player has a child with the same tag. Add in a Debug.Log in your OnTiggerEnter2D function along the lines of:

 Debug.Log(coll.transform.name);

To check to see if it is in fact the same gameobject triggering twice. If it is, a workaround I can suggest is to track player death with a boolean and add it to the if statement, ensuring the code doesn't get run twice. Something like this:

 var hasDied : boolean; //Declare wherever you want.
 
 function OnTriggerEnter2D(coll : Collider2D){
      var respawn = GameObject.Find("respawn");
      
      if (coll.gameObject.tag == "enemy" && !hasDied){
          hasDied = true;         
          deaths += 1;
          transform.position = Vector2(respawn.transform.position.x, respawn.transform.position.y);
          hasDied = false;
      }
  }

Also, pro-tip, if you're adding or subtracting '1' to a variable, a shortcut is to use ++ or --. Shorthand for writing += 1 or -= 1.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Corberius · Oct 23, 2015 at 05:29 AM

It keeps counting two deaths, here is the inspector details of the player and the wall:

alt text

alt text

And this is the ugly script of the player:

 #pragma strict
 
 public var points : int = 0;
 public var deaths : int = 0;
 var speed : float = 5f;
 var dir : String = String.Empty;
 var lastDir : String = String.Empty;
 var moveType : String = "normal";
 var newPos = Vector2.zero;
 var state : int = 0;
 var isDead : boolean = false;
 private var sfx : AudioSource[];
 sfx = GetComponents.<AudioSource>();
 
 function Start (){
     if (moveType == "slide"){
         newPos = Vector2(transform.position.x, transform.position.y);
     }
 }
 
 function Update (){
     direction ();
 }
 function FixedUpdate (){
     movement ();
 }
 
 function direction (){    
     if (state == 0 || state == 2){
         if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)){
             dir = "l";
         }
         if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)){
             dir = "r";
         }
         if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.W)){
         dir = "u";
         }
         if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)){
             dir = "d";
         }
     }
     if (Input.GetKeyDown(KeyCode.Escape) && state != 1){
         lastDir = dir;
         dir = "i";
         state = 1;
     }
 }
 
 function movement (){
     var damp : float = 0.1f;
     var velocity = Vector3.zero;
     
     if (dir != String.Empty || dir != "i"){
         if (dir == "l"){
             if (moveType == "normal"){
                 transform.Translate(-speed * Time.deltaTime, 0f, 0f, Space.World);
             }
             else if (moveType == "slide"){
                 newPos.x -= speed * Time.deltaTime;
             }
             transform.eulerAngles = Vector3(0f, 0f, 180f);
         }
         if (dir == "r"){
             if (moveType == "normal"){
                 transform.Translate(speed * Time.deltaTime, 0f, 0f, Space.World);
             }
             else if (moveType == "slide"){
                 newPos.x += speed * Time.deltaTime;
             }
             transform.eulerAngles = Vector3(0f, 0f, 0f);
         }
         if (dir == "u"){
             if (moveType == "normal"){
                 transform.Translate(0f, speed * Time.deltaTime, 0f, Space.World);
             }
             else if (moveType == "slide"){
                 newPos.y += speed * Time.deltaTime;
             }
             transform.eulerAngles = Vector3(0f, 0f, 90f);
         }
         if (dir == "d"){
             if (moveType == "normal"){
                 transform.Translate(0f, -speed * Time.deltaTime, 0f, Space.World);
             }
             else if (moveType == "slide"){
                 newPos.y -= speed * Time.deltaTime;
             }
             transform.eulerAngles = Vector3(0f, 0f, 270f);
         }
     }
     
     if (moveType == "slide"){
         if (dir != "i"){
             transform.position = Vector3.SmoothDamp(transform.position, newPos, velocity, damp);
         }
     }
 }
 
 function OnTriggerEnter2D(coll : Collider2D){
     var respawn = GameObject.Find("respawn");
     
     if (coll.gameObject.tag == "enemy" && !isDead){
         isDead = true;
         sfx[0].Play();
         deaths ++;
         dir = "i";
         transform.position = Vector2(respawn.transform.position.x, respawn.transform.position.y);
         newPos = Vector2(transform.position.x, transform.position.y);
         isDead = false;
     }
     if (coll.gameObject.tag == "slide"){
         newPos = Vector2(transform.position.x, transform.position.y);
         moveType = "slide";
     }
 }
 
 function OnTriggerExit2D(coll : Collider2D){
     if (coll.gameObject.tag == "slide"){
         moveType = "normal";
     }
 }    
 
 function LateUpdate(){
     var cam = GameObject.Find("MainCamera");
     var hud = GameObject.Find("HUD");
     //var controls = GameObject.Find("Controls");
     
     var hudPos = cam.GetComponent.<Camera>().ScreenToWorldPoint(Vector2(32f, Screen.height - 32f));
     //var conPos = cam.GetComponent.<Camera>().ScreenToWorldPoint(Vector2(Screen.width - 96f, 96f));
     
     hud.transform.position = hudPos;
     //controls.transform.position = conPos;
     cam.transform.position = Vector3(transform.position.x, transform.position.y, cam.transform.position.z);
 }
 
 function pointSound(point : int){
     if (point == 5){
         sfx[1].Play();
     }
     if (point == 10){
         sfx[2].Play();
     }
     if (point == 50){
         sfx[3].Play();
     }
     if (point == 100){
         sfx[4].Play();
     }
 }

example-2.png (56.0 kB)
example-3.png (31.9 kB)
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image seth_slax · Oct 23, 2015 at 06:59 AM 1
Share

I cant' see anything in the code that would cause this. Are there any children on the Player object, and if so, do any have colliders and share the same tag? Put the Debug.Log I posted above into the OnTriggerEnter2D function to print out the names of the objects that are being triggered. Only other solution I can think of at the moment is disabling the colldier of the Player object at the start of OnTriggerEnter2D, then re-enabling it after you've moved the object. Either that or adding a - yield WaitForSeconds(0.1); After moving it (and before switching the boolean again).

Also, just noticed something else; you mentioned the walls also have the "enemy" tag? From the image posted above, the player could be hitting two walls in the same frame, thus triggering it twice. If this is the case, there are a few solutions I can think of off the top of my head:

  • Parent all walls to a single gameobject with the "enemy" tag. This will compound all the colliders into one and register only one trigger.

  • As above, disable the Player collider on trigger (might not actually work though).

  • As above, add a delay before switching the boolean back.

  • $$anonymous$$ake different tags for the walls. (Again, might still call multiple triggers).

avatar image Corberius · Oct 23, 2015 at 07:38 AM 0
Share

In the console, I get two messages:

wall_1_v (2) (UnityEngine.BoxCollider2D) UnityEngine.Debug:Log(Object) Player:OnTriggerEnter2D(Collider2D) (at Assets/Scripts/Player.js:108) wall_1_v (3) (UnityEngine.BoxCollider2D) UnityEngine.Debug:Log(Object) Player:OnTriggerEnter2D(Collider2D) (at Assets/Scripts/Player.js:108)

Those walls are the duplicated vertical wall prefab (7 squares, xD), I will try to make a parent object for all the walls, but doing that... the walls will have a local coordinate from the parent, and not from the world. I prefer to change their position in 1 unit as 1 square... lol.

BTW, thank you very much for your help seth_slax :3 and I'm sorry for my bad english, spanish is my native language.

avatar image seth_slax Corberius · Oct 23, 2015 at 09:45 AM 1
Share

Yeah, the Log definitely suggests that it's hitting two walls simultaneously. You could unparent them, move them and re-parent them afterwards to keep their space local. There's probably an alternative, but I can't think of any at this point. Not a problem! Hope this helped.

avatar image Corberius seth_slax · Oct 23, 2015 at 11:02 PM 0
Share

Well, thank you very much for your help buddy, I will try to search more about it on google.

avatar image
0

Answer by epistomai · Nov 10, 2016 at 05:27 PM

I had the same issue, but worked for me. Now counts only once every instantiated gameObject:

 void OnTriggerEnter2D(Collider2D other) {
         
         if (!dead) {
             Destroy (other.gameObject);
             dead = true;
             Points++;
             Debug.Log (Points);
         }
     }
 
 void Update () {
         x -= 0.1f; //from right to left
         if (Convert.ToInt16 (((Time.time / 0.1f) * 2) % 3) == 0 || (y >= 3.8 && !(y < 3.8)) || (y <= -3.8 && !(y > -3.8))) {
             advance = advance * -1; //to switch upside/downside
         }
         y += 0.1f * advance;
 
         if (gameObject.activeInHierarchy) {
             gameObject.transform.position = new Vector3 (x, y, gameObject.transform.position.z);
         }
         if (x < -11) {
             Destroy (gameObject);
         }
         dead = false;
     }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

33 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How To Add Multiple 2d Box Colliders on Same Object for Different Effects 0 Answers

2D Colliders don't actually touch, causing problems 0 Answers

SImple but IMPOSSIBLE Enemies keep dying way ahead of time ! 0 Answers

NullreferenceException dealing damage to a child of the enemy 0 Answers

Need 2D help - Want to have object move towards point when it touches a trigger. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges