Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Ouija · Feb 15, 2015 at 09:07 PM · ainavmeshfunctionmouseclickwaypoint

Navmesh Enemy AI, Syntax issue?

THE VISUAL: The scene setup is a roaming enemy using waypoints (patrolling). When player is near, the enemy will chase the player and also shoot when close enough. If you MOUSECLICK on the enemy during any state Patrol/Chase/Shoot, it will cause him to walk to a set of Markers for brief time, eventually returning back to Patrol as he should.

The Problem: Everything seems to "kinda" work. It's a bit shaky. You have to click twice on the enemy to get him to run.(ONE click is desired result) First click the enemy will walk to its patrol waypoint than stop. Second Click he will then walk to the marker? I also think the speed of the run is interfering with the speed of his patrol walk?

 void Awake ()
     {
         markers = GameObject.FindGameObjectsWithTag("marker");
         // Setting up the references.
         enemySight = GetComponent<DoneEnemySight>();
         nav = GetComponent<NavMeshAgent>();
         player = GameObject.FindGameObjectWithTag(DoneTags.player).transform;
         lastPlayerSighting = GameObject.FindGameObjectWithTag(DoneTags.gameController).GetComponent<DoneLastPlayerSighting>();
         isClicked = false;
     }
     
     void OnMouseDown()
     {
         isClicked = true;
         StartCoroutine(WaitForSomeTime());
         Vector3 markerPos = markers[Random.Range(0, markers.Length)].transform.position;
         GetComponent<NavMeshAgent>().destination =  markerPos;
         posToCheck = markerPos;
         canCheckDistance = true;
     }
     
     void Update ()
     {
         if (isClicked) {
             Running ();
         }
         else if (enemySight.playerInSight) 
         {
             if (!isClicked) 
                 Shooting ();     
             }  
 
     else if (enemySight.personalLastSighting != lastPlayerSighting.resetPosition) {
             if (!isClicked) 
                 Chasing ();
         }
             else 
             {
                 if (!isClicked) 
                     Patrolling ();
                 }     
         }    
 
     void Running ()
     {
         nav.speed = runSpeed;
         if (canCheckDistance) {
             if (Vector3.Distance (transform.position, posToCheck) > distanceLimit - 0.5f) 
                 isClicked = false;
             canCheckDistance = false;
         }
     }
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Inan-Evin · Feb 15, 2015 at 09:29 PM

First you should decide in which condition the user will be able to click on the enemy and make it go somewhere else. You may want the enemy to be affected by mouse click only when patrolling, only when chasing, only when attacking, or in the situations that can be combination of these. Once you decide, we can show you exactly in which part of the code you should be building your logic. In this case, all I can tell you is that you need to create some logic with booleans. For example, create a private boolean called "isClicked".

 if(!isClicked)
 Shooting();
 
 if(!isClicked)
 Chasing();
 
 if(!isClicked)
 Patrolling();

this will disable those functions / states if isClick boolean is true. So, when you should make it true ?

 GameObject[] markers;
      
      void Start()
      {
          markers = GameObject.FindGameObjectsWithTag("marker");
          //requires you to tag every marker as "marker"
      }
      
      void OnMouseDown() // Requires a collider on your character
      {
          isClicked = true;
          //if you use NavMesh
          GetComponent<NavMeshAgent>().destination = markers[Random.Range(0, markers.Length)].transform.position;
      }

Now the AI will behave as usual, and when it is clicked it will stop processing those Shoot/Patrol/Chase behaviours and go to the random selected marker position. Now you need to make the isClicked variable false again for AIs to behave as expected, and it is up to you to decide when to make the variable false again.

- You can use a coroutine, give a desired time.

 GameObject[] markers;
 public float waitTime;
 
      void Start()
      {
          markers = GameObject.FindGameObjectsWithTag("marker");
          //requires you to tag every marker as "marker"
      }
      
      void OnMouseDown() // Requires a collider on your character
      {
          isClicked = true;
          //if you use NavMesh
          GetComponent<NavMeshAgent>().destination = markers[Random.Range(0, markers.Length)].transform.position;
 
          StartCoroutine(WaitForSomeTime());
      }
 
      IEnumerator WaitForSomeTime()
      {
        yield return new WaitForSeconds(waitTime);
        isClicked = false;
      }

And now the AI return to its normal behaviour.

- You can check the distance to the marker :

 GameObject[] markers;
 public float distanceLimit;
 private bool canCheckDistance;
 private Vector3 posToCheck;
      
      void Start()
      {
          markers = GameObject.FindGameObjectsWithTag("marker");
          //requires you to tag every marker as "marker"
      }
      
      void OnMouseDown() // Requires a collider on your character
      {
          isClicked = true;
          
          //if you use NavMesh
          Vector3 markerPos = markers[Random.Range(0, markers.Length)].transform.position;
          GetComponent<NavMeshAgent>().destination =  markerPos;
          posToCheck = markerPos;
          canCheckDistance = true;
      }
 
      void Update()
      {
       if(canCheckDistance)
       {
        if(Vector3.Distance(transform.position, posToCheck) > distanceLimit - 0.5f) // 0.5f is the margin
        {
          //reached
          isClicked = false;
          canCheckDistance = false;
         
        }
       }
      }

You can also combine the 1st and the 2nd way together. You can first check the distance, and if reached, start a coroutine, wait for some time and then make isClicked false again in order to make the AI start behaving normaly.

PS. I actually did not inspect the AI code too much, so you may need to reset or tweak some patrol point variables in order to make the AI behave correctly after moving to a marker, because it may be away from its origin position once you make it go somewhere else with mouse click and this can cause some issues. So this is the logic that you can built, I hope I've helped :).

Comment
Add comment · Show 5 · 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 Ouija · Feb 15, 2015 at 09:37 PM 0
Share

That was epic reply, I'm gonna go ahead and try to apply some of this logic to the AI script, see if i can get any results. $$anonymous$$ight take awhile for me lol but truly appricate it dude

avatar image Ouija · Feb 15, 2015 at 09:42 PM 0
Share

You were correct about that I should have mentioned I wanted to be able to click on the enemy during any state. Thanks for pointing that out

avatar image Inan-Evin · Feb 15, 2015 at 09:46 PM 0
Share

Well no problem, if got stuck in somewhere, just tell it out, I'll do my best to help!

avatar image Inan-Evin · Feb 15, 2015 at 10:14 PM 0
Share

It's because of your syntax, you need to open brackets after if statements, non bracked statements mean "read only the first line after this (first stated line)" So you should be doing this:

 private bool isClicked;

  void Update ()
      {
          // If the player is in sight and is alive...
          if(enemySight.playerInSight && playerHealth.health > 0f)
          {
              // ... shoot.
              if(!isClicked)
              Shooting();     
          } 
            
          // If the player has been sighted and isn't dead...
          else if(enemySight.personalLastSighting != lastPlayerSighting.resetPosition && playerHealth.health > 0f)
          {
              // ... chase.
              if(!isClicked)
              Chasing();
          }
              
          
          // Otherwise...
          else
          {
              // ... patrol.
              if(!isClicked)
              Patrolling();
          }
              
      }
avatar image Ouija · Feb 16, 2015 at 05:46 AM 0
Share

I feel like i'm close but still being a noob lol Everything seems to "kinda" work. It's a bit shaky. You have to click twice on the enemy to get him to run.(ONE click is desired result) First click the enemy will walk to its patrol waypoint than stop. Second Click he will then walk to the marker? I also think the speed of the run is interfering with the speed of his patrol walk?

 void Awake ()
     {
         markers = GameObject.FindGameObjectsWithTag("marker");
         // Setting up the references.
         enemySight = GetComponent<DoneEnemySight>();
         nav = GetComponent<Nav$$anonymous$$eshAgent>();
         player = GameObject.FindGameObjectWithTag(DoneTags.player).transform;
         lastPlayerSighting = GameObject.FindGameObjectWithTag(DoneTags.gameController).GetComponent<DoneLastPlayerSighting>();
         isClicked = false;
     }
     
     void On$$anonymous$$ouseDown()
     {
         isClicked = true;
         StartCoroutine(WaitForSomeTime());
         Vector3 markerPos = markers[Random.Range(0, markers.Length)].transform.position;
         GetComponent<Nav$$anonymous$$eshAgent>().destination =  markerPos;
         posToCheck = markerPos;
         canCheckDistance = true;
     }
     
     void Update ()
     {
         if (isClicked) {
             Running ();
         }
         else if (enemySight.playerInSight) 
         {
             if (!isClicked) 
                 Shooting ();     
             }  
 
     else if (enemySight.personalLastSighting != lastPlayerSighting.resetPosition) {
             if (!isClicked) 
                 Chasing ();
         }
             else 
             {
                 if (!isClicked) 
                     Patrolling ();
                 }     
         }    
 
     void Running ()
     {
         nav.speed = runSpeed;
         if (canCheckDistance) {
             if (Vector3.Distance (transform.position, posToCheck) > distanceLimit - 0.5f) 
                 isClicked = false;
             canCheckDistance = false;
         }
     }

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

20 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

Related Questions

Performing NPC movement with a function. 2 Answers

Navmesh Trouble 1 Answer

Why isn't a Ai Waypoint Spawning??? 0 Answers

Need help detecting barriers for my game 0 Answers

WayPoints mixed with Raycast 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