2015-11-30 6 views
3

, пожалуйста, посмотрите это короткое видео, чтобы увидеть проблему. Как только появляется около 23 символов, они начинают двигаться в разных направлениях. Пожалуйста, помогите мне, я стараюсь изо всех сил и искал несколько дней и пробовал различные подходы к поиску путей, но никто не выработал.Unity A * Pathfinding Project: Repath заставляет персонажа двигаться в противоположном направлении

http://screencast.com/t/sUx9O0I9GQ

Моя установка IST сетки и символы имеют AIPath с компонентом конфигурации по умолчанию прилагается. Должно быть возможно, потому что я видел его в стресс-тест видео: https://www.youtube.com/watch?v=htoen7x3LuQ

Эта строка кода вызывает тревогу:

seeker.StartPath (transform.position,target.transform.position, OnPathComplete); 

полный контекст

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; 
    } 
} 

Как говорит название, это Арон Гранбергс проект поиска пути http://arongranberg.com/astar/

Спасибо

+0

Пожалуйста, поделитесь функцией, которую 'StartPath' вызывает как обратный вызов. – mwilczynski

+0

Я добавил все методы из класса. В основном это пример кода из руководства по началу работы проекта звезды. Repath выполняется для обновления пути поддержки динамических препятствий. – zeiteisen

+0

Последнее, что я пропустил здесь для устранения неполадок, - это то, как вы вычисляете 'nextWaypointDistance'. Невозможно увидеть его где угодно. – mwilczynski

ответ

1

Хорошо, я играл с этой замечательной библиотекой AStar от Aron Granbergs, и я должен сказать, что, используя все инструкции и весь код из его учебника, это ... отлично работает.

Я использовал код, предоставленный Aron из его учебника здесь, добавив Destroy, который вы добавили тоже. Ссылка на учебник:http://arongranberg.com/astar/docs/getstarted.php

Код:

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; 
     } 
    } 
} 

Мои Player имеет Seeker, CharacterController и Rigidbody прикрепленную к ним. Я использую Sphere primitve так же, как вы, чтобы имитировать движение.

Я также добавил Duplicator для инстанцировании их по одному в небольших интервалах:

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; 
    } 
} 

Мой результат здесь: http://screencast.com/t/auTh0uvX

Пожалуйста, обратите внимание, Я не использовал Simple Smooth Modifier, поэтому мои сферы попадают в препятствие gr на одной из кривых.

Я проверил его с динамическим первопрохождения и вашей части кода:

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); 
} 

И результат, кажется, хорошо, но я могу видеть, что иногда ваш игрок может потерять путь на мгновение. Возможно, это зависит от производительности одного потока.

Мой выход 100 игроков,Instantiateраз в0.05s:

http://www.screencast.com/users/battlefist/folders/Jing/media/9039b000-cf61-4d11-9a91-573b98e6fd91

+0

Благодарю вас за усилия. Но вам не хватает одного важного шага. 'InvokeRepeating ("searchPath", 1.0f, 1.0f);'. Это нужно часто вызывать для поддержки динамического препятствия во время работы. – zeiteisen

+0

Ах, черт, кажется, я удалил это при копировании кода из учебника. Простите за это. – mwilczynski

+0

Я обновил свои тесты с помощью динамической проверки. Кажется, это не так плохо, как в вашем случае. – mwilczynski

1

Я получил ответ от Арона, автора А * проект поиска пути.

Привет

Это связано с высокой нагрузкой на систему поиска пути. Агент может запросить путь, когда он находится в какой-то момент, но поскольку для пути, который нужно вычислить, требуется некоторое время , агент переместится, когда он вернет результат . Сценарий AIPath пытается исправить это (если поле включено в поле closeestOnPathCheck включено), но он не может делать это в любое время. Решение состоит в том, чтобы уменьшить нагрузку на систему слежения и игру . Во-первых, убедитесь, что у вас включен многопоточность (A * Inspector -> Настройки), также, вероятно, неплохо отключить Show Graphs для больших графиков, так как рисование довольно медленное и значительно уменьшит . Вы также можете увеличить pickNextWaypointDistance и поля forwardLook на сценарии AIPath , что уменьшит вероятность этого.

Добавление модификатора raycast улучшит производительность даже больше. Бесплатная версия поддерживает только один поток и версию до 8.

 Смежные вопросы

  • Нет связанных вопросов^_^