• 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 Prefab · Jun 20, 2016 at 12:31 PM · triggerontriggerenterontriggerstaysingleone

How to allow only one object in a trigger at a time?

I have the following scenario (Diagram 1); the grey circles are AI agents and the green squares are trigger boxes. Diagram 2 is a zoomed in version of Diagram 1. Each trigger has the same tag, so an agent will look for the closest trigger to them and move towards it. When an agent's transform reaches the center of the trigger they start to earn points, and after a random amount of time they move on.

alt text

When an agent has started to earn points I'd like to change the trigger's tag to "occupied" so that other agents don't try to move to t$$anonymous$$s trigger, and instead look for the closest "vacant" one. The problem is the timing. I cannot change the tag OnTriggerEnter because the agent inside is still moving towards the center of the trigger, and therefore changing the tag would make it t$$anonymous$$nk the trigger is occupied and it would start looking for another trigger. But at the same time, not changing it allows other agents to continue to enter the trigger.

I have tried to change the tag during OnTriggerStay, as soon as the agent starts earning points. And when the agent leaves (OnTriggerExit), the tag is set back to vacant so that other agents can use it. The trouble here is that if there are multiple agents entering the trigger at around the same time, the trigger has no way of knowing the difference between them. For example, Agent 1 enters the trigger, but just before they reach the trigger's center, Agent 2 enters the trigger. At t$$anonymous$$s point there's two agents in the trigger, but the trigger doesn't know that. So Agent 1 could trigger OnTriggerEnter, w$$anonymous$$le Agent 2 can then trigger OnTriggerStay, skipping OnTriggerEnter.

And that is the basis of the issue. I would like to be able to have OnTriggerEnter, Stay and Exit triggered by only one agent at a time. How could I do t$$anonymous$$s?

Here is my script:

 using UnityEngine;
 using System.Collections;
 
 public class AICover : MonoBehaviour {
     
     public string enemyTag;
     public string coverFreeTag;
     public string coverNotFreeTag;
     public string uniqueID;
     private EnemyUniqueID enemyUniqueID;
     public bool almostNotFree = false;
     public Transform coverTransform;
     private NavMeshAgent enemyNavMeshAgentScript;
     private float enemyNavMeshAgentOrigRadius;
     
     // Use t$$anonymous$$s for initialization
     void Start () {
         coverTransform = transform;
         coverFreeTag = coverTransform.gameObject.tag;
     }
     
     // Update is called once per frame
     void Update () {
     
     }
     
     void OnTriggerEnter (Collider other) {
         if (other.CompareTag (enemyTag)) {
             enemyNavMeshAgentScript = other.GetComponent<NavMeshAgent> ();
             enemyNavMeshAgentOrigRadius = enemyNavMeshAgentScript.radius;
             enemyNavMeshAgentScript.radius = 0.0001f;
             if (coverTransform.gameObject.tag == coverFreeTag && !almostNotFree) {    
                 uniqueID = System.DateTime.Now.ToString ("ddMMyyyyHHmmss") + Random.Range (1, 1000).ToString ();
                 enemyUniqueID = other.GetComponent<EnemyUniqueID> ();
                 enemyUniqueID.enemyID = uniqueID;
                 almostNotFree = true;
             }
         }
     }
     
     void OnTriggerStay (Collider other) {
         if (other.CompareTag (enemyTag) && coverTransform.gameObject.tag == coverFreeTag && almostNotFree && uniqueID == enemyUniqueID.enemyID) {
             coverTransform.gameObject.tag = coverNotFreeTag;
         }
     }
     
     void OnTriggerExit (Collider other) {
         if (other.CompareTag(enemyTag)) {
             enemyUniqueID = other.GetComponent<EnemyUniqueID>();
             enemyNavMeshAgentScript.radius = enemyNavMeshAgentOrigRadius;
             if (coverTransform.gameObject.tag == coverNotFreeTag && almostNotFree && uniqueID == enemyUniqueID.enemyID) {
                 coverTransform.gameObject.tag = coverFreeTag;
                 almostNotFree = false;
             }
         }
     }
 }



diagrams.jpg (27.5 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

2 Replies

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

Answer by DiegoSLTS · Jun 20, 2016 at 01:18 PM

I'd do somet$$anonymous$$ng like t$$anonymous$$s:

  1. An agent looks for the closest non-ocuppied trigger

  2. The agent starts moving towards it

  3. On each update it checks if the trigger has become occupied by other. If it has, goes back to step 1

  4. If it enters a trigger, store a reference in that object to the agent that entered, t$$anonymous$$s would be the "occupied" flag.

  5. When it finished earning points, clear the object reference so other AI agents can move there even if the current one hasn't leave the trigger

So, when an agent checks if a square is occupied, it actually check if the reference is not null AND if it's no a reference to itself. In the case where two agents enter the same square, only one will make it as the reference, so the other one will move away form it.

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 Prefab · Jun 21, 2016 at 12:46 AM 0
Share
avatar image DiegoSLTS Prefab · Jun 21, 2016 at 01:44 AM 0
Share
avatar image Prefab DiegoSLTS · Jun 22, 2016 at 01:28 AM 0
Share
avatar image
1

Answer by glitchers · Jun 20, 2016 at 01:13 PM

Instead of changing tags on your cover objects use variables in your cover class. You can create a method to determine if an agent can move towards that as their target by returning if it is occupied.

Additionally for your uniqueID you can use System.Guid.NewGuid().ToString()(read more here)

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 Prefab · Jun 21, 2016 at 12:36 AM 0
Share

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

56 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

Related Questions

Issues trying to activate an image through OnTriggerEnter/Exit/Stay(Flickering) 1 Answer

Using triggers to then follow a specified path 0 Answers

About the door animation trigger 0 Answers

Open a canvas OnTriggerStay? 0 Answers

Calling "OnTriggerEnter" when a parent object has a rigidbody 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