Spherecast Repath Cost Traversing

Hi Aron & whom this may concern,

I appreciate your time to look at this as many others have come to you regarding this. I’ve looked into your documentation and also some forums, but i’m not quite wrapping my mind around the code necessary to fix my custom issue & seeing your definition page.

Platform: Unity3d 2019.2
Language: C#
Custom Local Avoidance Method: Raycast.Spherecast

Current Situation:
I’m able to stop the agents from traversing the path with your method of “canMove” set to false if the spherecast is within minDistance of another object.

What my intelligence is lacking:
Understanding how A* uses it’s nodes on a path from the seeker and using an for/foreach loop to see if current traversing path has a point where hit.point (from spherecast) is located & to set penalty to maximum on current path to recalculate path.

I’ve looked at ABPath but the majority of it is more private in nature & since i’m new to this A*'s asset methods (Which is more than a decades worth of work on your part) I’d thought i’d ask before dumping a month into investigating this issue.

Sincerely,
Sentar

Edited: 4/8/2020


I found your documentation for:

        ai.canSearch = false;
        var pointToAvoid = currentHitObject.transform.position;
        // Make the AI flee from the enemy.
        // The path will be about 20 world units long (the default cost of moving 1 world unit is 1000).
        var path = FleePath.Construct(ai.position, pointToAvoid, 1000 * 20);
        ai.SetPath(path);

Which is incredibly helpful and now I’ll have to figure out if other agent made it to the target position, and then use my offset calculations to form a battle circle around the target.

Sincerely,
Sentar

1 Like

Sounds like you found what you were looking for?

Unfortunately not quite as when the FleePath is finished the AI will retraverse the same path; instead of, setting the cost to a high value on the existing path.

Edited: 4/8/2020

It looks like GetRemainingPath may be the key, but my if statement for getting the correct buffer spot is faulty.

var buffer = new List();
ai.GetRemainingPath(buffer, out bool stale);

        for (int i = 0; i < buffer.Count - 1; i++)
        {
            if (new Vector3(currentHitObject.transform.position.x, 0, currentHitObject.transform.position.z) == new Vector3(buffer[i].x, 0, buffer[i + 1].z))
            {
                calculateNewPath = true;
                Debug.Log("NPC position pathway is being used");
            }
        }

        if (calculateNewPath == true)
        {
            //recalculate w/ higher cost
        }

Edit 4/8/2020 FinalResult

Hi Aron,

After I realized that my method was not ideal. You already had a resolution. I dived into your RVO Group Controller and pulled out your code (If you want me to not do this PLEASE let me know).

Here is the updated version of your code that I can now use in my project as needed (ofcourse it will be edited by my encirclement solution etc. as I will make a single close encirclement then have the rest offset each other etc. etc. etc.

Picture:

Code that worked in the demo:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding.RVO;
using Pathfinding.RVO.Sampled;

public class NPC_AI_Battle_Circle : MonoBehaviour
{
public GameObject[] ais;
List<Pathfinding.Examples.RVOExampleAgent> selection = new List<Pathfinding.Examples.RVOExampleAgent>();
public Transform target;
public Vector3 targetLastPos;

public bool set;

// Update is called once per frame
void Update()
{
    if (ais.Length != selection.Count)
    {
        foreach (GameObject ai in ais)
        {
            if (!selection.Contains(ai.GetComponent<Pathfinding.Examples.RVOExampleAgent>()))
            {
                selection.Add(ai.GetComponent<Pathfinding.Examples.RVOExampleAgent>());
            }
        }
    }

    if (target.position != targetLastPos)
    {
        set = false;
        targetLastPos = target.position;
    }

    if (ais.Length == selection.Count && set == false)
    {
        float radsum = 0;
        for (int i = 0; i < selection.Count; i++) radsum += selection[i].GetComponent<RVOController>().radius;

        float radius = radsum / (Mathf.PI);
        radius *= 2f;

        for (int i = 0; i < ais.Length; i++)
        {
            float deg = 2 * Mathf.PI * i / ais.Length;
            Vector3 p = targetLastPos + new Vector3(Mathf.Cos(deg), 0, Mathf.Sin(deg)) * radius;
            //Debug.DrawRay (p,Vector3.up*4,Color.cyan);
            //Debug.Break();
            selection[i].SetTarget(p);
          //  selection[i].SetColor(GetColor(deg));
            selection[i].RecalculatePath();
          
        }

        set = true;
    }
    
}

}

Thank you for taking the time to at least reply to my post. It is a privilege to stand before a legend and one day I hope to get as good as you.

Sincerely,
Sentar

1 Like

You can close this post.