• 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 SmokeyDB · Oct 31, 2013 at 09:27 AM · ontriggerexit

Alternative to OnTriggerExit?

I'm currently using OnTriggerExit to respawn a blocks once the player leaves the area. There are multiple blocks per level. They are platforms that disappear if the player stays on them too long.

The OnTriggerExit doesn't seem reliable to me. Sometimes it runs and sometimes it doesn't. I'm really looking for an alternative to OnTriggerExit.

The issue is, 95% of the time, the respawn fine, however 5% of the time, they won't respawn.

Vanish Block Script

 #pragma strict
 private var animPlaying = false;
 private var delayedEnable = false;
 private var isIn = false;
 private var timeElapsed : float = 0;
 private var vanished = false;
 
 function Start () {
     gameObject.GetComponent(AnimatedSpritesheet).columns = 8;
     gameObject.GetComponent(AnimatedSpritesheet).framesPerSecond = 0;
     gameObject.GetComponent(AnimatedSpritesheet).repeat = false;
     gameObject.GetComponent(AnimatedSpritesheet).SetFrameOrder([0]);
 }
 
 function Update () {
     if (delayedEnable){    
         if (!isIn){
             EnableCollider();
             delayedEnable = false;
         }
     }
 }
 
 function PlayAnimation () {
     if (!animPlaying){
         DropCollider();
         animPlaying = true;
         gameObject.GetComponent(AnimatedSpritesheet).columns = 8;
         gameObject.GetComponent(AnimatedSpritesheet).framesPerSecond = 8;
         gameObject.GetComponent(AnimatedSpritesheet).repeat = false;
         gameObject.GetComponent(AnimatedSpritesheet).SetFrameOrder([0,1,2,3,4,5,6,7]);
     }
     //Debug.Log("Anim Playing: " + animPlaying);
 }
 
 function PlayReverseAnim (){
     gameObject.GetComponent(AnimatedSpritesheet).columns = 8;
     gameObject.GetComponent(AnimatedSpritesheet).framesPerSecond = 8;
     gameObject.GetComponent(AnimatedSpritesheet).repeat = false;
     gameObject.GetComponent(AnimatedSpritesheet).SetFrameOrder([7,6,5,4,3,2,1,0]);
     //Debug.Log("Reverse Anim Playing: " + animPlaying);
 }
 
 function DropCollider (){
     yield WaitForSeconds (1.0);
     //collider.enabled = false;
     vanished = true;
     yield WaitForSeconds (1.0);
     if (!isIn){
         EnableCollider();
     }
     else {
         delayedEnable = true;
     }    
 }
 
 function EnableCollider (){
     PlayReverseAnim();
     //collider.enabled = true;
     vanished = false;
     yield WaitForSeconds (1.0);
     animPlaying = false;
 }
 
 function isInYes(){
     isIn = true;
 }
 
 function isInNo(){
     isIn = false;
 }
 
 function OnTriggerEnter (other : Collider){
     if (vanished == false){
         if (other.CompareTag("Player")){
             isInYes();
             PlayAnimation();
             Debug.Log("Trigger Entered by " + other.name);
         }
     }
 }
 
 function OnTriggerExit (other : Collider){
     if (vanished == true){
         if (other.CompareTag("Player"))
         {
             isInNo();
             Debug.Log("Trigger Exited by " + other.name);
         }
     }
 }
Comment
Add comment · Show 6
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 Tomer-Barkan · Oct 31, 2013 at 06:57 AM 0
Share

please organize your code in a code segment (button above text area)

avatar image sdgd · Oct 31, 2013 at 09:29 AM 0
Share

he said webside is wierd and it won't let him organize his code correctly

I'm doing now 2 things: sending a report and giving help so he might learn how to do it.

  • if you want to tag code please watch this

  • crap I can't send to mod so someone would saw it and repare it with enough karma

avatar image SmokeyDB · Oct 31, 2013 at 01:56 PM 0
Share

I've gone through and manually spaced the code since the tags are not working for me. I'm still looking for a solution to this issue. Thanks =)

avatar image Tomer-Barkan · Oct 31, 2013 at 02:04 PM 0
Share

I've never encountered any issues with OnTriggerExit(). Is it possible that you are destroying the game object before the OnTriggerExit() is called?

If this is the case, you can handle what happens when the object is destroyed by adding the OnDestroy() method:

http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$onoBehaviour.OnDestroy.html

avatar image SmokeyDB · Oct 31, 2013 at 02:28 PM 0
Share

I checked that but that doesn't seem to be the issue. The game objects are never actually destroyed, the block's collider is disabled as the animation turns it transparent.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Tomer-Barkan · Oct 31, 2013 at 02:52 PM

Right, similar to the destroy issue, but not quite.

For the OnTriggerExit() to be called, you need an active collider. Once you disable the collider, the object will be skipped in the collision detection phase, so the OnTriggerExit() will not be called.

Instead of deactivating the collider, set a boolean variable vanished = true, and whenever a collision occurs, check whether the vanished variable is true or false. If false, then return without doing anything, this will be the same as disabling the collider.

Edit: Here's the code that should achieve what you're looking for. Untested.

 #pragma strict
 private var vanishing = false;
 private var appearing = false;
  
 function Start () {
     gameObject.GetComponent(AnimatedSpritesheet).columns = 8;
     gameObject.GetComponent(AnimatedSpritesheet).framesPerSecond = 0;
     gameObject.GetComponent(AnimatedSpritesheet).repeat = false;
     gameObject.GetComponent(AnimatedSpritesheet).SetFrameOrder([0]);
 }
  
 function Update () {
     if (vanishing) {
         DropCollider();
     }
     
     if (appearing) {
         EnableCollider();
     }
 }
  
 function PlayAnimation () {
    gameObject.GetComponent(AnimatedSpritesheet).columns = 8;
    gameObject.GetComponent(AnimatedSpritesheet).framesPerSecond = 8;
    gameObject.GetComponent(AnimatedSpritesheet).repeat = false;
    gameObject.GetComponent(AnimatedSpritesheet).SetFrameOrder([0,1,2,3,4,5,6,7]);
 }
  
 function PlayReverseAnim (){
     gameObject.GetComponent(AnimatedSpritesheet).columns = 8;
     gameObject.GetComponent(AnimatedSpritesheet).framesPerSecond = 8;
     gameObject.GetComponent(AnimatedSpritesheet).repeat = false;
     gameObject.GetComponent(AnimatedSpritesheet).SetFrameOrder([7,6,5,4,3,2,1,0]);
 }
  
  // play animation, wait 1 second, and then make block fall-through
 function DropCollider (){
     PlayAnimation();
     yield WaitForSeconds (1.0);
     collider.isTrigger = true;
     vanishing = false;
 }
  
 // play reverse animation, wait 1 second, then make block solid
 function EnableCollider (){
     PlayReverseAnim();
     yield WaitForSeconds (1.0);
     collider.isTrigger = false;
     appearing = false;
 }
  
 // when player collides with block, start vanishing sequence
 function OnCollisionEnter (collision : Collision){
    if (collision.collider.CompareTag("Player")){
      vanishing = true;
    }
 }
  
 // when player leaves block area when block is fall-through (trigger) - start reappear sequence
 function OnTriggerExit (other : Collider){
    if (other.CompareTag("Player")){
      appearing = true;
    }
 }
Comment
Add comment · Show 20 · 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 SmokeyDB · Oct 31, 2013 at 03:15 PM 0
Share

I'm not understanding how the collider is every going to be disabled if I'm never actually setting it to collider.enabled to false; I have gone through and changed it to use a bool ins$$anonymous$$d of the collider.enabled and the animation seems to be working ok however, the collider is never disabled.

avatar image Tomer-Barkan · Oct 31, 2013 at 03:21 PM 0
Share

The trick was not to disable the collider, but ins$$anonymous$$d just ignore it when you handle the collision in OnTriggerEnter() and OnTriggerExit().

The result is the same as disabling it. Another option might be to manually call OnTriggerExit() when you disable the collider, because it will not be called automatically when the collider is disabled.

avatar image SmokeyDB · Oct 31, 2013 at 03:40 PM 0
Share

I think I'm confused about when the collision occurs. OnTriggerEnter() is what is checking for collision. When there is collision I check to see if vanished is false and if so, play the animation. Am I able to use collider.enabled inside the OnTriggerEnter()? Even if I return without doing anything, the collider is never disabled.

avatar image SmokeyDB · Oct 31, 2013 at 03:44 PM 0
Share

I've updated my code based on your suggestions so you can see what's going on now. I've deleted the extra script and added the collision checks in the vanishBlock script.

avatar image Tomer-Barkan · Oct 31, 2013 at 03:55 PM 1
Share

I'm not exactly sure what you're trying to do, but let me try to explain.

OnTriggerEnter() is called when a trigger collider collides with another collider. So far fine, and OnTriggerEnter() is called. Now, OnTriggerExit() is called in the first frame when a trigger collider no longer collides with the other collider.

Now, if OnTriggerEnter() is called, but you disabled the collider before the collision ended (ie before the colliders separated), then the OnTriggerExit() never gets called.

Now change your code like this:

 function OnTriggerEnter (other : Collider){
     if (other.CompareTag("Player")){
         isInYes();
         PlayAnimation();
         Debug.Log("Trigger Entered by " + other.name);
     }
 }
  
 function OnTriggerExit (other : Collider){
     if (other.CompareTag("Player"))
     {
         isInNo();
         Debug.Log("Trigger Exited by " + other.name);
         if (vanished) {
             collider.enabled = false; 
         }
     }
 }

This is supposed to be similar to your original code, except that ins$$anonymous$$d of disabling the collider in the middle of the collision, you set vanished to true, and you disable the collider only after the OnTriggerExit() has been called.

Show more comments

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

17 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

Related Questions

A node in a childnode? 1 Answer

OnTriggerExit is not firing in 3.2 1 Answer

What game engine was the series "Slender man's shadow" made on. 1 Answer

Collision Detection with a Rigid Player Object 1 Answer

Button to change layers 1 Answer


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