- Home /
Move randomly NPC using A* pathfinding
Is there a way to move my NPC randomly over all map using A* pathfinding? I've tried using this, but it's not effective because NPC sometimes walks against the wall:
// Forces NPC to move randomly
void MoveRandomly () {
if (tempTimer > 0) {
tempTimer -= Time.deltaTime;
}
else {
tempTimer = Random.Range (4, 16);
lookingAt = new Vector3 (Random.Range (transform.position.x - 8, transform.position.x + 8), 0, Random.Range (transform.position.z - 8, transform.position.z + 8));
}
lookingAt.y = transform.position.y;
cNavMesh.destination = lookingAt;
// Play animation
if (cNavMesh.destination == lookingAt) {
animation.Play ("idle");
}
else {
animation.Play ("walk");
}
}
Answer by Spherical Cow · Dec 09, 2013 at 01:25 PM
Not sure if you've already figured this out, but here is a solution I implemented for a kids "zombie survival" game using the aron A*Pathfinding ( http://arongranberg.com/astar/front ).
It will randomly generate a coordinate between max/min x/z values you set and keep your NPC's facing the direction they are moving (and not the final destination). Adding animation and AI behavior to it would be easy enough.
If you have any questions feel free to ask.
Hope it helps!
A.
using UnityEngine;
using System.Collections;
using Pathfinding;
[AddComponentMenu ("Enemy/Pathfinding")]
public class EnemyPathfinding : MonoBehaviour {
private Transform myTransform;
public float rotationSpeed = 1f;
//The point to move to
public Vector3 targetPosition;
private Seeker seeker;
private CharacterController controller;
//The calculated path
public Path path;
//The AI's speed per second
float speed = 100;
//The max distance from the AI to a waypoint for it to continue to the next waypoint
public float nextWaypointDistance = 3;
//The waypoint we are currently moving towards
private int currentWaypoint = 0;
public int xMax;
public int xMin;
public int zMax;
public int zMin;
public int randomX;
public int randomZ;
public bool didFindPath;
public bool endOfPath;
public float moveSpeed;
public void Start () {
endOfPath = true;
didFindPath = false;
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
myTransform = transform;
}
public void GetPath(){
//Start a new path to the targetPosition, return the result to the OnPathComplete function
targetPosition = new Vector3(randomX, 0, randomZ);
seeker.StartPath (transform.position,targetPosition, OnPathComplete);
}
public void OnPathComplete (Path p) {
if (!p.error)
{
path = p;
currentWaypoint = 0;
}
}
public void Update(){
if(transform.position.x <= targetPosition.x + 5 && transform.position.x >= targetPosition.x - 5)
didFindPath = false;
if(!didFindPath)
{
randomX = Random.Range(xMin, xMax);
randomZ = Random.Range(zMin, zMax);
didFindPath = true;
GetPath();
}
moveSpeed = rigidbody.velocity.magnitude;
if(path !=null)
{
Vector3 moveDir = path.vectorPath[currentWaypoint] - myTransform.position;
// Rotate towards the target
myTransform.rotation = Quaternion.Slerp (myTransform.rotation, Quaternion.LookRotation(moveDir), rotationSpeed * Time.deltaTime);
myTransform.eulerAngles = new Vector3(0, myTransform.eulerAngles.y, 0);
}
}
public void FixedUpdate () {
if (path == null)
{
//We have no path to move after yet
return;
}
// finds end of path
if (currentWaypoint >= path.vectorPath.Count)
{
print ("end of path");
return;
}
//Direction to the next waypoint
Vector3 dir = (path.vectorPath[currentWaypoint]-transform.position).normalized;
dir *= speed * Time.fixedDeltaTime;
controller.SimpleMove (dir);
//Check if we are close enough to the next waypoint
//If we are, proceed to follow the next waypoint
if (Vector3.Distance (transform.position,path.vectorPath[currentWaypoint]) < nextWaypointDistance)
{
currentWaypoint++;
return;
}
}
}
Your answer
Follow this Question
Related Questions
How do you set up navmesh agents to go to multiple destinations? 3 Answers
Non-player movement 1 Answer
How to use A* pathfinding for a large map? 2 Answers
How to change a NavMeshAgent angular rotation speed, 0 Answers
Sidescroller NPC follows Player 0 Answers