//generic version public static void Raycast(Vector3 origin, Vector3 direction, AgentProperties properties, out RaycastHitNavMesh hit, float length = 1000f, bool triggeredByPassabilityChange = true, bool triggeredByAreaChange = true, int maxIterations = 100) { //try get cell at target position Cell cell; bool outsideCell; if (TryGetCell(origin, properties, out cell, out outsideCell) == false || outsideCell) { hit = new RaycastHitNavMesh(origin, false); return; } Raycast(origin, direction, properties, out hit, length, triggeredByPassabilityChange, triggeredByAreaChange, maxIterations, cell.passability, cell.area, cell); }
//targeted by area and passability public static void Raycast(Vector3 origin, Vector3 direction, AgentProperties properties, out RaycastHitNavMesh hit, Area expectedArea, Passability expectedPassability, float length = 1000f, int maxIterations = 100) { //try get cell at target position Cell cell; bool outsideCell; if (TryGetCell(origin, properties, out cell, out outsideCell) == false || outsideCell) { hit = new RaycastHitNavMesh(origin, false); return; } //cell we found are not with expected area or passability if (cell.area != expectedArea | cell.passability != expectedPassability) { hit = new RaycastHitNavMesh(origin, true); return; } Raycast(origin, direction, properties, out hit, length, true, true, maxIterations, expectedPassability, expectedArea, cell); }
//private raycasting to take input by things upside private static void Raycast(Vector3 origin, Vector3 direction, AgentProperties properties, out RaycastHitNavMesh hit, float length, bool triggeredByPassabilityChange, bool triggeredByAreaChange, int maxIterations, Passability expectedPassability, Area expectedArea, Cell cell) { raycastExclude.Clear();//excluded list of edges float maxLengthSqr = length * length; for (int iteration = 0; iteration < maxIterations; iteration++) { raycastTempData.Clear();//iteration data cleared foreach (var pair in cell.dataContentPairs) { CellContentData curData = pair.Key; if (!raycastExclude.Add(curData))//mean it's already contain this { continue; } Vector3 intersect; if (SomeMath.RayIntersectXZ(origin, direction, curData.leftV3, curData.rightV3, out intersect)) { if (pair.Value != null) { Cell otherCell = pair.Value.connection; if (otherCell == cell | !otherCell.canBeUsed) { continue; } if ((triggeredByPassabilityChange && cell.passability != otherCell.passability) || (triggeredByAreaChange && cell.area != otherCell.area)) { hit = new RaycastHitNavMesh(intersect, SomeMath.SqrDistance(origin, intersect) < maxLengthSqr); return; } raycastTempData.Add(new RaycastSomeData(intersect, otherCell)); } else { raycastTempData.Add(new RaycastSomeData(intersect, null)); } } } //check if there possible connection for (int i = 0; i < raycastTempData.Count; i++) { if (raycastTempData[i].cell != null) { cell = raycastTempData[i].cell; goto CONTINUE; } } //now we definetly hit something and now find furthest float furthestSqrDist = 0f; Vector3 furthest = origin; for (int i = 0; i < raycastTempData.Count; i++) { float curSqrDist = SomeMath.SqrDistance(raycastTempData[i].point, origin); if (curSqrDist > furthestSqrDist) { furthestSqrDist = curSqrDist; furthest = raycastTempData[i].point; } } hit = new RaycastHitNavMesh(furthest, SomeMath.SqrDistance(origin, furthest) < maxLengthSqr); return; CONTINUE : { continue; } } hit = new RaycastHitNavMesh(origin, true, true); return; }