A* Pathfinding Project

RichAI.SetPath with RVO not working in 4.3.14


#1

Why Cache Path

  • in my game, the map is never change when created
  • each time , i need create 300~400 unit at point A, and ask them move to point B (with RVO)

How To

  • use ABPath.Construct to request a path instance
  • Claim the path
  • use richAI.SetPath in the loop to set the path directly

Full Code

using System.Collections;
using System.Collections.Generic;
using Pathfinding;
using UnityEngine;
using UnityEngine.UI;

public class NavTest1 : MonoBehaviour
{
    public Button cachePathGenBtn;
    public Button normalGenBtn;
    public Toggle isUseEnumerator;

    public int agentNum;

    public GameObject Agent;
    public Transform startPos;
    public Transform aimTarget;

    private Path mPath;
    private bool mIsNotTick;

    private void Start()
    {
        cachePathGenBtn.onClick.AddListener(OnClickCacheGenWithEnumeratorBtn);
        normalGenBtn.onClick.AddListener(OnClickNormalGen);
    }

    private void OnClickCacheGenWithEnumeratorBtn()
    {
        if (mPath == null)
        {
            mPath = ABPath.Construct(startPos.position, aimTarget.position, (p) => { Debug.Log($"Not useful because Path PipelineState = {p.PipelineState} not PathState.Returned"); });
            AstarPath.StartPath(mPath);
            mIsNotTick = false;
        }
        else
        {
            if (isUseEnumerator.isOn)
            {
                StartCoroutine(CacheGenWithEnumerator());
            }
            else
            {
                CacheGenDirectly();
            }
        }
    }

    private void OnClickNormalGen() { NormalGen(); }

    private void Update()
    {
        if (mPath == null || mIsNotTick) return;

        if (mPath.PipelineState == PathState.Returned)
        {
            mIsNotTick = true;

            mPath.Claim(this);
            var m = new StartEndModifier();
            m.Apply(mPath);

            if (isUseEnumerator.isOn)
            {
                StartCoroutine(CacheGenWithEnumerator());
            }
            else
            {
                CacheGenDirectly();
            }
        }
    }

    private void NormalGen()
    {
        for (int i = 0; i < agentNum; i++)
        {
            var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
            agentGo.GetComponent<RichAI>().destination = aimTarget.position;
        }
    }

    private IEnumerator CacheGenWithEnumerator()
    {
        yield return null;
        var list = new List<RichAI>();
        for (var i = 0; i < agentNum; i++)
        {
            var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
            list.Add(agentGo.GetComponent<RichAI>());
        }

        yield return null;
        list.ForEach(richAI => richAI.SetPath(mPath));
    }

    private void CacheGenDirectly()
    {
        for (var i = 0; i < agentNum; i++)
        {
            var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
            agentGo.GetComponent<RichAI>().SetPath(mPath);
        }
    }


    private Vector3 GetRanStartPos()
    {
        var b = startPos.position;
        b.x += Random.Range(-0.1f, 0.1f);
        b.z += Random.Range(-0.1f, 0.1f);
        return b;
    }
}

Issue

ABPath.Construct callback not working on multi-thread

mPath = ABPath.Construct(startPos.position, aimTarget.position, (p) => { Debug.Log($"Not useful because Path PipelineState = {p.PipelineState} not PathState.Returned"); });

output:

Not useful because Path PipelineState = ReturnQueue not PathState.Returned

in RichAI.cs SetPath function , it only accept PathState.Created or PathState.Returned

so ,in my previous code . i use the Update function to wait it finish

Create agent at exact same position RVO will not working

   private Vector3 GetRanStartPos()
   {
        var b = startPos.position;
        b.x += Random.Range(-0.1f, 0.1f);
        b.z += Random.Range(-0.1f, 0.1f);
        return b;
    }

   for (int i = 0; i < agentNum; i++)
   {
         var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
          agentGo.GetComponent<RichAI>().destination = aimTarget.position;
   }

if just Instantiate all agent at same position same frame. all agent will follow the path without RVO.

Some agent not move with no error.

    private IEnumerator CacheGenWithEnumerator()
    {
        yield return null;
        var list = new List<RichAI>();
        for (var i = 0; i < agentNum; i++)
        {
            var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
            list.Add(agentGo.GetComponent<RichAI>());
        }

        yield return null;
        list.ForEach(richAI => richAI.SetPath(mPath));
    }

    private void CacheGenDirectly()
    {
        for (var i = 0; i < agentNum; i++)
        {
            var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
            agentGo.GetComponent<RichAI>().SetPath(mPath);
        }
    }

when try to use cache path create 100 agents, some of them (around 20) can follow the path to move.
reset of them not move at all. and i can’t find any error output in my Console. (A* log level already set to heavy)

if i use normal gen function, everything work fine

    private void NormalGen()
    {
        for (int i = 0; i < agentNum; i++)
        {
            var agentGo = Instantiate(Agent, GetRanStartPos(), Quaternion.identity);
            agentGo.GetComponent<RichAI>().destination = aimTarget.position;
        }
    }

Demo Project

Unity : 2019.3.3f1
Burst: 1.2.3
A*Project: 4.3.14

Download Link


#2

Hi

This may or may not be related to the draw gizmos bug you also discovered?

I have fixed this now in version 4.3.15.