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 /
avatar image
0
Question by szaboa22 · Aug 09, 2017 at 07:16 PM · collisioncollider2d game2d-physicsloop

*** Trigger Collider2D event only once ***

Hello there,

I have some difficulties executing a Collision2D trigger event only once. For a top-down 2D game with melee fight, I am using a Capsule Collider 2D for dealing damage to the enemy. Whenever the attack key ('Space') is pressed, the Capsule Collider2D attached to the player is activated and any enemy within the range of this collider is damaged.

Now this part of the script works fine. The problem is, that when the OnTriggerEnter2D event is triggered, it should be executed only once and decrease enemy health by 1. The code in the script looks like this:

 public class enemyControl : MonoBehaviour {
 
     public int enemyHealth = 3;
 
     public GameObject enemy;
 
     public SpriteRenderer enemySprite;
     public Sprite enemyDead;
 
     public Collider2D enemyCollider;
     public Collider2D damageCollider;
     public Collider2D playerAttack;
 
     void OnTriggerEnter2D (Collider2D playerAttack) {
 
         if (playerAttack.tag == "plrAttack") {
 
                 enemyHealth-=1;
 
         }
     }
 
     void Start () {
         
         enemySprite = GetComponent<SpriteRenderer> ();
     }
 
     void Update () {
    
         if (enemyHealth <= 0) 
         {
 
             enemySprite.sprite = enemyDead;
             enemyCollider.enabled = false;
         }
         
     }
 }

The problem is that whenever I press the attack key ('Space'), the collision trigger starts a very fast loop that decreases the enemy's health to zero immediately. Is there some way to break this "loop" after only one execution?

I have to add, that I have searched the forum for possible solutions, including using OnTriggerExit and introducing a boolean value for checking the state of the trigger, but none of that seemed to work as the loop just goes on.

The attack action script looks like this, btw.:

 if (Input.GetKey (KeyCode.Space) && !moving) {
             playerAnimator.SetBool ("isAttacking", true);
             attack.enabled = true;
             fighting = true;
         }

"attack.enabled = true" is the row that enables the Capsule Collider 2D that is dealing the damage.

I would really appreciate any help or hints as I am stuck with this unnerving problem for days...

Many thanks!

Comment
Add comment · Show 1
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 bobisgod234 · Aug 10, 2017 at 12:12 AM 0
Share

You could:

  • Use Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.Space) ins$$anonymous$$d of Input.Get$$anonymous$$ey ($$anonymous$$eyCode.Space)

  • Use an animation event as part of the attack animation, and do an overlap test.

Also try:

 if (!attack.enabled)
     attack.enabled = true;

to avoid setting it to enabled each frame.

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by unidad2pete · Aug 09, 2017 at 08:06 PM

Try making a new bool to check if collider has been triggered on each hit.

 public bool hitCheck;
 
 void OnTriggerEnter2D (Collider2D playerAttack) {
  
          if (playerAttack.tag == "plrAttack" && !hitCheck) {
  
                  enemyHealth-=1;
                  hitCheck = true;
  
          }
      }

set hitCheck to false again on your Input Space for example.

Comment
Add comment · Show 3 · 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 szaboa22 · Aug 10, 2017 at 03:10 AM 0
Share

Hello! Thanks for the reply, I really appreciate your help!

I tried the following:

 public bool takingDamage;
 
 void OnTriggerEnter2D (Collider2D playerAttack) {
 
         if (playerAttack.tag == "plrAttack" && !takingDamage) {
 
                 enemyHealth-=1;
                 takingDamage = true;
         }
     }

And I have added this to the playerControl script:

 if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.Space) && !moving) {
             enemy.takingDamage = false;
             playerAnimator.SetBool ("isAttacking", true);
             attack.enabled = true;
             fighting = true;
         }

Now this seems to successfully stop the loop after one frame and hit; the enemy suffers one health damage as intended, but the takingDamage bool just won't flip back to false (even though I also changed the input method to Get$$anonymous$$eyDown from Get$$anonymous$$ey) after executing the loop once.

avatar image unidad2pete szaboa22 · Aug 10, 2017 at 03:42 AM 0
Share

why enemy.takingDamage = false;?? its takingDamage = false;

avatar image szaboa22 unidad2pete · Aug 10, 2017 at 07:28 AM 0
Share

Because it is in a different script (the one controlling the player) attached to a different game object (the player object). I aim to change the Boolean variable of the script controlling the enemy from within my player controller script. Am I doing it wrong?

avatar image
0

Answer by merkaba48 · Aug 09, 2017 at 09:55 PM

If you've tried using a bool state to track if it's been hit that frame or not, and it still doesn't work, the problem might be elsewhere. Have you tried using the debugger and putting a breakpoint in the OnTrigger method, then seeing how many times it's called? Or even just printing something to the console inside the method.

Comment
Add comment · Show 1 · 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 szaboa22 · Aug 10, 2017 at 02:49 AM 0
Share

Hi there! Thanks for your reply!

I did - the loop executes 8 to 10 times per button hit.

avatar image
0

Answer by szaboa22 · Aug 10, 2017 at 06:22 PM

@unidad2pete I think I have found the root problem why the boolean checker value ("takingDamage") won't flip back to "false" when hitting the attack button.

All the enemies are instantiated as clones from a prefab at random points inside the procedurally generated dungeon. Even though I reference the GameObject / prefab in the script, the variable change won't apply to the clones. I have searched through the forum, but couldn't find any viable solution.

Could you please look at my below script and provide me with any hints regarding how could I reference the prefab clone variables?

Many thanks!

  /* I have removed some of this script for now as it is irrelevant to the question */
 
 public class playerControl : MonoBehaviour {
 
 
     public GameObject enemy;
     enemyControl ec;  //for referencing another script 
 
     public Animator playerAnimator;
     private bool moving = false;
     private bool fighting = false;
 
     public Collider2D attack; // referencing the attack collider
 
     void Start () {
 
         playerAnimator = GetComponent<Animator>();
         playerAnimator.SetBool ("isMoving", false);
         playerAnimator.SetBool ("isAttacking", false);
 
         attack.enabled = false;
         ec = enemy.GetComponent<enemyControl> ();
 
 
     }
 
     void Update ()
     {
 
 if (Input.GetKey (KeyCode.Space) && !moving) {
             ec.takingDamage = false; //it won't flip back to false on the clones!
             playerAnimator.SetBool ("isAttacking", true);
             attack.enabled = true;
             fighting = true;
 
         }
 
     }
 }

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

119 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 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 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 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

Trigger2D not working 0 Answers

Creating 'redstone' like wires 1 Answer

Problem with collision with two colliders simultaneously in Unity 2D 1 Answer

Unity 2D Collider Safe Sizes 0 Answers

How to tell if a 2D object is in a certain area 2 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