- A* version: 5.3.8
- Unity version: 22.3.62
What’s a better way to find cover on a recast navmesh?
I have this and it seems sub optimal.
bool SetDestination_Cover()
{
// Search for a cover where the enemy has no line of sight.
var possibleCovers = new List<Vector3>();
float searchRadius = 3.0f;
int n = 20; // Maxiumum number of candidate cover points.
int s = 10; // Number of sample per circle
bool isSet = false;
var attacker = self.shotBy!=null ? self.shotBy : self.target;
if(attacker) {
// Sample random cover points on an increasing circle.
var src = attacker.HeadPosition; //transform.position;
var pos = transform.position;
var ignoredColliders = attacker.colliders.Union(self.colliders);
while (possibleCovers.Count<n) {
for (int i = 0;i<s;i++) {
float a = Random.value*Mathf.PI*2.0f;
var dst = pos+new Vector3(Mathf.Cos(a),0.0f,Mathf.Sin(a))*searchRadius;
// check LOS from attacker to random position
if(!self.HasLOS(src,dst,ignoredColliders)) possibleCovers.Add(dst);
}
searchRadius += 3.0f;
}
// Search the closest cover point
UnityEngine.AI.NavMeshPath selfPath = new UnityEngine.AI.NavMeshPath();
UnityEngine.AI.NavMeshPath attackerPath = new UnityEngine.AI.NavMeshPath();
Vector3 closest = pos;
float minD = float.PositiveInfinity;
foreach (var p in possibleCovers) {
if(UnityEngine.AI.NavMesh.CalculatePath(agent.transform.position,p,new NavMeshQueryFilter() { agentTypeID = agent.agentTypeID,areaMask = agent.areaMask }
,selfPath)
&& selfPath.status==UnityEngine.AI.NavMeshPathStatus.PathComplete) {
// if ( agent.CalculatePath(p, selfPath) && selfPath.status == NavMeshPathStatus.PathComplete) {
float attackerDistance = 0.0f;
if(attacker!=null && attacker.TryGetComponent<UnityEngine.AI.NavMeshAgent>(out var attackerAgent) && attackerAgent.CalculatePath(p,attackerPath))
attackerDistance = PathLength(attackerPath);
float d = PathLength(selfPath)-attackerDistance*0.1f;
if(d<minD) {
minD = d;
closest = p;
}
}
}
SetDestination(closest);
isSet = true;
}
return isSet;
}
so I turned it into that but it doesn’t seem super efficient either (pasting breaks formatting so here is a screencap).
