Reputation: 7168
please watch this short video to see the problem. As soon as there are about 23 characters they start moving in different directions. Please help me, I'm trying my best and searched for days and tried diffenrent pathfinding approaches but none worked out.
http://screencast.com/t/sUx9O0I9GQ
My setup ist a grid and the characters have a AIPath with default configuration component attached. It must be possible because I saw it in the stress test video: https://www.youtube.com/watch?v=htoen7x3LuQ
This line of code causes the trouble:
seeker.StartPath (transform.position,target.transform.position, OnPathComplete);
The complete context
public void Start () {
InvokeRepeating ("searchPath", 1.0f, 1.0f);
searchPath ();
}
public void searchPath() {
GameObject target = GameObject.Find ("Target");
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
//Start a new path to the targetPosition, return the result to the OnPathComplete function
seeker.StartPath (transform.position,target.transform.position, OnPathComplete);
}
public void OnPathComplete (Path p) {
Debug.Log ("Yay, we got a path back. Did it have an error? "+p.error);
if (!p.error) {
path = p;
//Reset the waypoint counter
currentWaypoint = 0;
}
}
public void Update () {
if (path == null) {
//We have no path to move after yet
return;
}
if (currentWaypoint >= path.vectorPath.Count) {
Debug.Log ("End Of Path Reached");
Destroy(gameObject);
return;
}
//Direction to the next waypoint
Vector3 dir = (path.vectorPath[currentWaypoint]-transform.position).normalized;
dir *= speed * Time.deltaTime;
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;
}
}
As the title says, it's Aron Granbergs pathfinding project http://arongranberg.com/astar/
Thank you
Upvotes: 3
Views: 4403
Reputation: 3082
Alright, I've played around with this wonderful AStar library from Aron Granbergs and I must say that using all the instructions and all the code from his tutorial it's... working just fine.
I've used the code provided by Aron from his tutorial up here, adding Destroy
that you've added too.
Link to tutorial: http://arongranberg.com/astar/docs/getstarted.php
Code:
using UnityEngine;
using Pathfinding;
public class PlayerScript : MonoBehaviour {
public Vector3 targetPosition;
private Seeker seeker;
private CharacterController controller;
//The calculated path
public Path path;
//The AI's speed per second
public 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 void Start()
{
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
//Start a new path to the targetPosition, return the result to the OnPathComplete function
targetPosition = GameObject.Find("Target").transform.localPosition;
seeker.StartPath(transform.position, targetPosition, OnPathComplete);
}
public void OnPathComplete(Path p)
{
Debug.Log("Yay, we got a path back. Did it have an error? " + p.error);
if (!p.error)
{
path = p;
//Reset the waypoint counter
currentWaypoint = 0;
}
}
public void Update()
{
if (path == null)
{
//We have no path to move after yet
return;
}
if (currentWaypoint >= path.vectorPath.Count)
{
Debug.Log("End Of Path Reached");
Destroy(gameObject);
return;
}
//Direction to the next waypoint
Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;
dir *= speed * Time.deltaTime;
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;
}
}
}
My Player
has Seeker
, CharacterController
and Rigidbody
attached to them. I'm using Sphere primitve same as you do to simulate movement.
I've also added Duplicator
for instantiating them one by one in small intervals:
PlayerDuplicator:
using UnityEngine;
using System.Collections;
public class PlayerDuplicator : MonoBehaviour
{
public GameObject PlayerPrefab;
public uint HowMany = 50;
public float Interval = 0.2f;
public Vector3 InstantiatePosition;
// Use this for initialization
void Start ()
{
StartCoroutine("DeployPlayers");
}
// Update is called once per frame
void Update () {
}
public IEnumerator DeployPlayers()
{
if (PlayerPrefab == null) yield break;
while (HowMany > 0)
{
var player = Instantiate(PlayerPrefab);
player.transform.position = InstantiatePosition;
HowMany--;
yield return new WaitForSeconds(Interval);
}
yield return null;
}
}
My outcome is here: http://screencast.com/t/auTh0uvX
Please note I did not use Simple Smooth Modifier
so my spheres are hitting the obstacle gracefully on one of the curves.
I've tested it with dynamic pathfinding and your part of code:
public void Start()
{
InvokeRepeating("searchPath", 1.0f, 1.0f);
searchPath();
}
public void searchPath()
{
GameObject target = GameObject.Find("Target");
seeker = GetComponent<Seeker>();
controller = GetComponent<CharacterController>();
//Start a new path to the targetPosition, return the result to the OnPathComplete function
seeker.StartPath(transform.position, target.transform.position, OnPathComplete);
}
And the outcome seem fine, but I can see your that sometimes player can lose the path for a moment. It might be indeed dependent on performance of a single thread.
My output with 100 players, Instantiate
once per 0.05s
:
http://www.screencast.com/users/battlefist/folders/Jing/media/9039b000-cf61-4d11-9a91-573b98e6fd91
Upvotes: 1
Reputation: 7168
I got a response from Aron, the author of the A* pathfinding project.
Hi
This is due to a high load on the pathfinding system. An agent might request a path when it is at some point, but since it takes some time for the path to be calculated, the agent will have moved when it gets the result back. The AIPath script tries to fix this (assuming the closestOnPathCheck field is enabled) but it cannot do it at all times. The solution is to reduce the load on the pathfinding system and the game. First, make sure you have multithreading enabled (A* Inspector -> Settings), also it is probably a good idea to turn off Show Graphs for larger graphs since drawing that is pretty slow and will reduce the fps significantly. You can also increase the pickNextWaypointDistance and the forwardLook fields on the AIPath script, that will reduce the chance of this happening.
Adding the raycast modifier will improve the performance even more. The free version only supports one thread and the pro version up to 8.
Upvotes: 2