From 8722a9920c1f6119bf6e769cba270e63097f8e25 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Thu, 23 May 2024 10:08:29 +0800 Subject: + astar project --- .../Graphs/Grid/Jobs/JobNodeWalkability.cs | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Jobs/JobNodeWalkability.cs (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Jobs/JobNodeWalkability.cs') diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Jobs/JobNodeWalkability.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Jobs/JobNodeWalkability.cs new file mode 100644 index 0000000..7629df7 --- /dev/null +++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Grid/Jobs/JobNodeWalkability.cs @@ -0,0 +1,73 @@ +using UnityEngine; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; + +namespace Pathfinding.Graphs.Grid.Jobs { + /// Calculates for each grid node if it should be walkable or not + [BurstCompile(FloatMode = FloatMode.Fast)] + public struct JobNodeWalkability : IJob { + /// + /// If true, use the normal of the raycast hit to check if the ground is flat enough to stand on. + /// + /// Any nodes with a steeper slope than will be made unwalkable. + /// + public bool useRaycastNormal; + /// Max slope in degrees + public float maxSlope; + /// Normalized up direction of the graph + public Vector3 up; + /// If true, nodes will be made unwalkable if no ground was found under them + public bool unwalkableWhenNoGround; + /// For layered grid graphs, if there's a node above another node closer than this distance, the lower node will be made unwalkable + public float characterHeight; + /// Number of nodes in each layer + public int layerStride; + + [ReadOnly] + public NativeArray nodePositions; + + public NativeArray nodeNormals; + + [WriteOnly] + public NativeArray nodeWalkable; + + public void Execute () { + // Cosinus of the max slope + float cosMaxSlopeAngle = math.cos(math.radians(maxSlope)); + float4 upNative = new float4(up.x, up.y, up.z, 0); + float3 upNative3 = upNative.xyz; + + for (int i = 0; i < nodeNormals.Length; i++) { + // walkable will be set to false if no ground was found (unless that setting has been disabled) + // The normal will only be non-zero if something was hit. + bool didHit = math.any(nodeNormals[i]); + var walkable = didHit; + if (!didHit && !unwalkableWhenNoGround && i < layerStride) { + walkable = true; + // If there was no hit, but we still want to make the node walkable, then we set the normal to the up direction + nodeNormals[i] = upNative; + } + + // Check if the node is on a slope steeper than permitted + if (walkable && useRaycastNormal && didHit) { + // Take the dot product to find out the cosine of the angle it has (faster than Vector3.Angle) + float angle = math.dot(nodeNormals[i], upNative); + + // Check if the ground is flat enough to stand on + if (angle < cosMaxSlopeAngle) { + walkable = false; + } + } + + // Check if there is a node above this one (layered grid graph only) + if (walkable && i + layerStride < nodeNormals.Length && math.any(nodeNormals[i + layerStride])) { + walkable = math.dot(upNative3, nodePositions[i + layerStride] - nodePositions[i]) >= characterHeight; + } + + nodeWalkable[i] = walkable; + } + } + } +} -- cgit v1.1-26-g67d0