• 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
Question by Greg 9 · Feb 07, 2012 at 03:00 PM · javascriptaipathfindingconvert

A* Pathfinding AIFollow in JavaScript?

Is there a JavaScript equivalent to Aron Granberg's A* Pathfinding AIFollow.cs script?

I'm using ListGraph based pathfinding and want to disable the canMove variable on AIFollow.cs when the player collides with a collider. I write all my other scripts in JavaScript and have little understanding of C#.

Ideally I'd need an AIFollow.js for my AI to communiate with the pathfinding system and use the listGraphs like the C# equivalent does.

alternatively, I'd like to know how to set the canMove variable to false from a seperate script (JavaScript). i.e. changing the variable of a C# script by sending a message from a JavaScript. But this really doesn't seem like a great alternative.

Here is the C# code:

 using UnityEngine;

using System.Collections; using Pathfinding;

/** Example AI */ [RequireComponent (typeof(Seeker))] [RequireComponent (typeof(CharacterController))] public class AIFollow : MonoBehaviour {

 /** Target to move to */
 public Transform target;
 
 /** How often to search for a new path */
 public float repathRate = 0.1F;
 
 /** The minimum distance to a waypoint to consider it as "reached" */
 public float pickNextWaypointDistance = 1F;
 
 /** The minimum distance to the end point of a path to consider it "reached" (multiplied with #pickNextWaypointDistance).
  * This value is multiplied with #pickNextWaypointDistance before it is used. Recommended range [0...1] */
 public float targetReached = 0.2F;
 
 /** Units per second */
 public float speed = 5;
 
 /** How fast the AI can turn around */
 public float rotationSpeed = 1;
 
 public bool drawGizmos = false;
 
 /** Should paths be searched for.
  * Setting this to false will make the AI not search for paths anymore, can save some CPU cycles.
  * It will check every #repathRate seconds if it should start to search for paths again.
  * \note It will not cancel paths which are currently being calculated */
 public bool canSearch = true;
 
 /** Can it move. Enables or disables movement and rotation */
 public bool canMove = true;
 
 /** Seeker component which handles pathfinding calls */
 protected Seeker seeker;
 
 /** CharacterController which handles movement */
 protected CharacterController controller;
 
 /** NavmeshController which handles movement if not null*/
 protected NavmeshController navmeshController;
 
 
 /** Transform, cached because of performance */
 protected Transform tr;
 
 protected float lastPathSearch = -9999;
 
 protected int pathIndex = 0;
 
 /** This is the path the AI is currently following */
 protected Vector3[] path;
 
 /** Use this for initialization */
 public void Start () {
     seeker = GetComponent<Seeker>();
     controller = GetComponent<CharacterController>();
     navmeshController = GetComponent<NavmeshController>();
     
     tr = transform;
     Repath ();
 }
 
 /** Called when a path has completed it's calculation */
 public void OnPathComplete (Path p) {
     
     /*if (Time.time-lastPathSearch >= repathRate) {
         Repath ();
     } else {*/
         StartCoroutine (WaitToRepath ());
     //}
     
     //If the path didn't succeed, don't proceed
     if (p.error) {
         return;
     }
     
     //Get the calculated path as a Vector3 array
     path = p.vectorPath;
     
     //Find the segment in the path which is closest to the AI
     //If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then
     float minDist = Mathf.Infinity;
     int notCloserHits = 0;
     
     for (int i=0;i<path.Length-1;i++) {
         float dist = Mathfx.DistancePointSegmentStrict (path[i],path[i+1],tr.position);
         if (dist < minDist) {
             notCloserHits = 0;
             minDist = dist;
             pathIndex = i+1;
         } else if (notCloserHits > 6) {
             break;
         }
     }
 }
 
 /** Waits the remaining time until the AI should issue a new path request.
  * The remaining time is defined by Time.time - lastPathSearch */
 public IEnumerator WaitToRepath () {
     float timeLeft = repathRate - (Time.time-lastPathSearch);
     
     yield return new WaitForSeconds (timeLeft);
     Repath ();
 }
 
 /** Stops the AI.
  * Also stops new search queries from being made
  * \version Before 3.0.8 This does not prevent new path calls from making the AI move again
  * \see #Resume
  * \see #canMove
  * \see #canSearch */
 public void Stop () {
     canMove = false;
     canSearch = false;
 }
 
 /** Resumes walking and path searching the AI.
  * \version Added in 3.0.8
  * \see #Stop
  * \see #canMove
  * \see #canSearch */
 public void Resume () {
     canMove = true;
     canSearch = true;
 }
 
 /** Recalculates the path to #target.
   * Queries a path request to the Seeker, the path will not be calculated instantly, but will be put on a queue and calculated as fast as possible.
   * It will wait if the current path request by this seeker has not been completed yet.
   * \see Seeker::IsDone */
 public virtual void Repath () {
     lastPathSearch = Time.time;
     
     if (seeker == null || target == null || !canSearch || !seeker.IsDone ()) {
         StartCoroutine (WaitToRepath ());
         return;
     }
     
     /*ConstantPath cpath = new ConstantPath(transform.position,null);
     //Must be set to avoid it from searching towards Vector3.zero
     cpath.heuristic = Heuristic.None;
     //Here you set how far it should search
     cpath.maxGScore = 2000;
     AstarPath.StartPath (cpath);*/
     //FloodPathTracer fpathTrace = new FloodPathTracer (transform.position,fpath,null);
     //seeker.StartPath (fpathTrace,OnPathComplete);
     
     //Start a new path from transform.positon to target.position, return the result to the function OnPathComplete
     seeker.StartPath (transform.position,target.position,OnPathComplete);
 }
 
 /** Start a new path moving to \a targetPoint */
 public void PathToTarget (Vector3 targetPoint) {
     lastPathSearch = Time.time;
     
     if (seeker == null) {
         return;
     }
     
     //Start a new path from transform.positon to target.position, return the result to OnPathComplete
     seeker.StartPath (transform.position,targetPoint,OnPathComplete);
 }
 
 /** Called when the AI reached the end of path.
  * This will be called once for every path it completes, so if you have a really fast repath rate it will call this function often if when it stands on the end point.
  */
 public virtual void ReachedEndOfPath () {
     //The AI has reached the end of the path
 }
 
 /** Update is called once per frame */
 public void Update () {
     
     if (path == null || pathIndex >= path.Length || pathIndex < 0 || !canMove) {
         return;
     }
     
     //Change target to the next waypoint if the current one is close enough
     Vector3 currentWaypoint = path[pathIndex];
     currentWaypoint.y = tr.position.y;
     while ((currentWaypoint - tr.position).sqrMagnitude < pickNextWaypointDistance*pickNextWaypointDistance) {
         pathIndex++;
         if (pathIndex >= path.Length) {
             //Use a lower pickNextWaypointDistance for the last point. If it isn't that close, then decrement the pathIndex to the previous value and break the loop
             if ((currentWaypoint - tr.position).sqrMagnitude < (pickNextWaypointDistance*targetReached)*(pickNextWaypointDistance*targetReached)) {
                 ReachedEndOfPath ();
                 return;
             } else {
                 pathIndex--;
                 //Break the loop, otherwise it will try to check for the last point in an infinite loop
                 break;
             }
         }
         currentWaypoint = path[pathIndex];
         currentWaypoint.y = tr.position.y;
     }
     
     
     Vector3 dir = currentWaypoint - tr.position;
     
     // Rotate towards the target
     tr.rotation = Quaternion.Slerp (tr.rotation, Quaternion.LookRotation(dir), rotationSpeed * Time.deltaTime);
     tr.eulerAngles = new Vector3(0, tr.eulerAngles.y, 0);
     
     Vector3 forwardDir = transform.forward;
     //Move Forwards - forwardDir is already normalized
     forwardDir = forwardDir * speed;
     forwardDir *= Mathf.Clamp01 (Vector3.Dot (dir.normalized, tr.forward));
     
     if (navmeshController != null) {
         navmeshController.SimpleMove (tr.position,forwardDir);
     } else {
         controller.SimpleMove (forwardDir);
     }
     
 }
 
 /** Draws helper gizmos.
  * Currently draws a circle around the current target point with the size showing how close the AI need to get to it for it to count as "reached".
  */
 public void OnDrawGizmos () {
     
     if (!drawGizmos || path == null || pathIndex >= path.Length || pathIndex < 0) {
         return;
     }
     
     Vector3 currentWaypoint = path[pathIndex];
     currentWaypoint.y = tr.position.y;
     
     Debug.DrawLine (transform.position,currentWaypoint,Color.blue);
     
     float  rad = pickNextWaypointDistance;
     if (pathIndex == path.Length-1) {
         rad *= targetReached;
     }
     
     Vector3 pP = currentWaypoint + rad*new Vector3 (1,0,0);
     for (float i=0;i<2*System.Math.PI;i+= 0.1F) {
         Vector3 cP = currentWaypoint + new Vector3 ((float)System.Math.Cos (i)*rad,0,(float)System.Math.Sin(i)*rad);
         Debug.DrawLine (pP,cP,Color.yellow);
         pP = cP;
     }
     Debug.DrawLine (pP, currentWaypoint + rad*new Vector3 (1,0,0),Color.yellow);
 }

}

Anyone know any links to JavaScript alternatives? Anyone have a JavaScript alternative? Any suggestions at all?

Thanks

Comment

People who like this

0 Show 0
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

0 Replies

· Add your reply
  • Sort: 

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

array of boxes 2 Answers

A* optimization and path help 0 Answers

AI Pathfinding Script 4 Answers

Basic Enemy Javascript 0 Answers

Follow up to AI Pathfinding Question 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