コード例 #1
0
        /** Returns the position with the correct height.
         * If #heightCheck is false, this will return \a position.\n
         * \a walkable will be set to false if nothing was hit.
         * The ray will check a tiny bit further than to the grids base to avoid floating point errors when the ground is exactly at the base of the grid
         */
        public Vector3 CheckHeight(Vector3 position, out RaycastHit hit, out bool walkable)
        {
            walkable = true;

            if (!heightCheck || use2D)
            {
                hit = new RaycastHit();
                return(position);
            }

            if (thickRaycast)
            {
                var ray = new Ray(position + up * fromHeight, -up);
                if (Physics.SphereCast(ray, finalRaycastRadius, out hit, fromHeight + 0.005F, heightMask))
                {
                    return(VectorMath.ClosestPointOnLine(ray.origin, ray.origin + ray.direction, hit.point));
                }

                walkable &= !unwalkableWhenNoGround;
            }
            else
            {
                // Cast a ray from above downwards to try to find the ground
                if (Physics.Raycast(position + up * fromHeight, -up, out hit, fromHeight + 0.005F, heightMask))
                {
                    return(hit.point);
                }

                walkable &= !unwalkableWhenNoGround;
            }
            return(position);
        }
コード例 #2
0
        /** Same as #CheckHeight, except that the raycast will always start exactly at \a origin.
         * \a walkable will be set to false if nothing was hit.
         * The ray will check a tiny bit further than to the grids base to avoid floating point errors when the ground is exactly at the base of the grid
         */
        public Vector3 Raycast(Vector3 origin, out RaycastHit hit, out bool walkable)
        {
            walkable = true;

            if (!heightCheck || use2D)
            {
                hit = new RaycastHit();
                return(origin - up * fromHeight);
            }

            if (thickRaycast)
            {
                var ray = new Ray(origin, -up);
                if (Physics.SphereCast(ray, finalRaycastRadius, out hit, fromHeight + 0.005F, heightMask))
                {
                    return(VectorMath.ClosestPointOnLine(ray.origin, ray.origin + ray.direction, hit.point));
                }

                walkable &= !unwalkableWhenNoGround;
            }
            else
            {
                if (Physics.Raycast(origin, -up, out hit, fromHeight + 0.005F, heightMask))
                {
                    return(hit.point);
                }

                walkable &= !unwalkableWhenNoGround;
            }
            return(origin - up * fromHeight);
        }
コード例 #3
0
 // Token: 0x060024D6 RID: 9430 RVA: 0x0019D518 File Offset: 0x0019B718
 public Vector3 CheckHeight(Vector3 position, out RaycastHit hit, out bool walkable)
 {
     walkable = true;
     if (!this.heightCheck || this.use2D)
     {
         hit = default(RaycastHit);
         return(position);
     }
     if (this.thickRaycast)
     {
         Ray ray = new Ray(position + this.up * this.fromHeight, -this.up);
         if (Physics.SphereCast(ray, this.finalRaycastRadius, out hit, this.fromHeight + 0.005f, this.heightMask, QueryTriggerInteraction.Collide))
         {
             return(VectorMath.ClosestPointOnLine(ray.origin, ray.origin + ray.direction, hit.point));
         }
         walkable &= !this.unwalkableWhenNoGround;
     }
     else
     {
         if (Physics.Raycast(position + this.up * this.fromHeight, -this.up, out hit, this.fromHeight + 0.005f, this.heightMask, QueryTriggerInteraction.Collide))
         {
             return(hit.point);
         }
         walkable &= !this.unwalkableWhenNoGround;
     }
     return(position);
 }
コード例 #4
0
 public Vector3 CheckHeight(Vector3 position, out RaycastHit hit, out bool walkable)
 {
     walkable = true;
     if (!this.heightCheck || this.use2D)
     {
         hit = new RaycastHit();
         return(position);
     }
     if (this.thickRaycast)
     {
         Ray ray = new Ray(position + ((Vector3)(this.up * this.fromHeight)), -this.up);
         if (Physics.SphereCast(ray, this.finalRaycastRadius, out hit, this.fromHeight + 0.005f, (int)this.heightMask))
         {
             return(VectorMath.ClosestPointOnLine(ray.origin, ray.origin + ray.direction, hit.point));
         }
         walkable &= !this.unwalkableWhenNoGround;
         return(position);
     }
     if (Physics.Raycast(position + ((Vector3)(this.up * this.fromHeight)), -this.up, out hit, this.fromHeight + 0.005f, (int)this.heightMask))
     {
         return(hit.point);
     }
     walkable &= !this.unwalkableWhenNoGround;
     return(position);
 }
コード例 #5
0
        // Update is called once per frame
        void LateUpdate()
        {
            if (prevNode == null)
            {
                var nninfo = AstarPath.active.GetNearest(transform.position);
                prevNode = nninfo.node;
                prevPos  = transform.position;
            }

            if (prevNode == null)
            {
                return;
            }

            if (prevNode != null)
            {
                var graph = AstarData.GetGraph(prevNode) as IRaycastableGraph;
                if (graph != null)
                {
                    GraphHitInfo hit;
                    if (graph.Linecast(prevPos, transform.position, prevNode, out hit))
                    {
                        hit.point.y = transform.position.y;
                        Vector3 closest = VectorMath.ClosestPointOnLine(hit.tangentOrigin, hit.tangentOrigin + hit.tangent, transform.position);
                        Vector3 ohit    = hit.point;
                        ohit = ohit + Vector3.ClampMagnitude((Vector3)hit.node.position - ohit, 0.008f);
                        if (graph.Linecast(ohit, closest, hit.node, out hit))
                        {
                            hit.point.y        = transform.position.y;
                            transform.position = hit.point;
                        }
                        else
                        {
                            closest.y = transform.position.y;

                            transform.position = closest;
                        }
                    }
                    prevNode = hit.node;
                }
            }

            prevPos = transform.position;
        }
コード例 #6
0
 // Token: 0x06002440 RID: 9280 RVA: 0x00196CB8 File Offset: 0x00194EB8
 private void LateUpdate()
 {
     if (this.prevNode == null)
     {
         NNInfo nearest = AstarPath.active.GetNearest(base.transform.position);
         this.prevNode = nearest.node;
         this.prevPos  = base.transform.position;
     }
     if (this.prevNode == null)
     {
         return;
     }
     if (this.prevNode != null)
     {
         IRaycastableGraph raycastableGraph = AstarData.GetGraph(this.prevNode) as IRaycastableGraph;
         if (raycastableGraph != null)
         {
             GraphHitInfo graphHitInfo;
             if (raycastableGraph.Linecast(this.prevPos, base.transform.position, this.prevNode, out graphHitInfo))
             {
                 graphHitInfo.point.y = base.transform.position.y;
                 Vector3 vector  = VectorMath.ClosestPointOnLine(graphHitInfo.tangentOrigin, graphHitInfo.tangentOrigin + graphHitInfo.tangent, base.transform.position);
                 Vector3 vector2 = graphHitInfo.point;
                 vector2 += Vector3.ClampMagnitude((Vector3)graphHitInfo.node.position - vector2, 0.008f);
                 if (raycastableGraph.Linecast(vector2, vector, graphHitInfo.node, out graphHitInfo))
                 {
                     graphHitInfo.point.y    = base.transform.position.y;
                     base.transform.position = graphHitInfo.point;
                 }
                 else
                 {
                     vector.y = base.transform.position.y;
                     base.transform.position = vector;
                 }
             }
             this.prevNode = graphHitInfo.node;
         }
     }
     this.prevPos = base.transform.position;
 }
コード例 #7
0
 private void LateUpdate()
 {
     if (this.prevNode == null)
     {
         NNInfo nearest = AstarPath.active.GetNearest(base.transform.position);
         this.prevNode = nearest.node;
         this.prevPos  = base.transform.position;
     }
     if (this.prevNode != null)
     {
         if (this.prevNode != null)
         {
             IRaycastableGraph graph = AstarData.GetGraph(this.prevNode) as IRaycastableGraph;
             if (graph != null)
             {
                 GraphHitInfo info2;
                 if (graph.Linecast(this.prevPos, base.transform.position, this.prevNode, out info2))
                 {
                     info2.point.y = base.transform.position.y;
                     Vector3 end   = VectorMath.ClosestPointOnLine(info2.tangentOrigin, info2.tangentOrigin + info2.tangent, base.transform.position);
                     Vector3 point = info2.point;
                     point += Vector3.ClampMagnitude(((Vector3)info2.node.position) - point, 0.008f);
                     if (graph.Linecast(point, end, info2.node, out info2))
                     {
                         info2.point.y           = base.transform.position.y;
                         base.transform.position = info2.point;
                     }
                     else
                     {
                         end.y = base.transform.position.y;
                         base.transform.position = end;
                     }
                 }
                 this.prevNode = info2.node;
             }
         }
         this.prevPos = base.transform.position;
     }
 }
コード例 #8
0
ファイル: AstarMath.cs プロジェクト: hackerlank/UnityGameSrc
 public static Vector3 NearestPoint(Vector3 lineStart, Vector3 lineEnd, Vector3 point)
 {
     return(VectorMath.ClosestPointOnLine(lineStart, lineEnd, point));
 }
コード例 #9
0
        // this function keeps the path generated away from the edge of the nav mesh, replacing funnel path points which are on a triangle vertex
        // with new points which are offset into the triangle away from the vertex
        private void PadFunnelPath(ref List <Vector3> funnelPath, ref List <GraphNode> path, Path _p)
        {
            ABPath      abPath          = _p as ABPath;
            const float SamePositionSqr = 0.001f * 0.001f;

            bool skipFirstPoint = false;
            bool skipLastPoint  = false;

            if (null != abPath && funnelPath.Count > 0)
            {   // don't want to mess with the start point
                if (VectorMath.SqrDistanceXZ(funnelPath[0], abPath.originalStartPoint) < SamePositionSqr)
                {
                    skipFirstPoint = true;
                }
                // don't want to mess with the end point
                if (VectorMath.SqrDistanceXZ(funnelPath[funnelPath.Count - 1], abPath.originalEndPoint) < SamePositionSqr)
                {
                    skipLastPoint = true;
                }
            }

            int startNode = 0;

            for (int point = 0; point < funnelPath.Count; ++point)
            {
                Vector3 funnelPoint = funnelPath[point];

                if (0 == point && skipFirstPoint)
                {
                    continue;
                }

                if (funnelPath.Count - 1 == point && skipLastPoint)
                {
                    continue;
                }

                bool hasPointBeenRemoved = false; // we will remove the funnel path point if it is found to be on a triangle vertex (it'll be replaced with offset points)

                ++startNode;
                // go over all points apart from the end node, as we don't want to add new path points in the end node as that node contains the target position
                for (int node = startNode; node < path.Count - 1; ++node)
                {
                    if (node < 0 || node >= path.Count)
                    {
                        continue;
                    }
                    TriangleMeshNode theNode = path[node] as TriangleMeshNode;

                    Vector3[] vertices = new Vector3[3] {
                        (Vector3)theNode.GetVertex(0), (Vector3)theNode.GetVertex(1), (Vector3)theNode.GetVertex(2)
                    };

                    for (int vert = 0; vert < 3; ++vert)
                    {
                        if (VectorMath.SqrDistanceXZ(funnelPoint, vertices[vert]) < SamePositionSqr) // the triangle has a vertex on the funnel path
                        {
                            bool isNodeOnTheLine = false;
                            // in this section we test if the triangle has an edge on the funnel path
                            if (point < funnelPath.Count - 1) // we need another point after point
                            {
                                Vector3 nextFunnelPoint  = funnelPath[point + 1];
                                Vector3 vertNotOnTheLine = new Vector3(); // if two of our triangle verts are on the funnel path, this is the other vert
                                if (VectorMath.SqrDistanceXZ(vertices[(vert + 2) % 3], nextFunnelPoint) < SamePositionSqr)
                                {
                                    isNodeOnTheLine  = true;
                                    vertNotOnTheLine = vertices[(vert + 1) % 3]; // other point is next
                                }
                                else if (VectorMath.SqrDistanceXZ(vertices[(vert + 1) % 3], nextFunnelPoint) < SamePositionSqr)
                                {
                                    isNodeOnTheLine  = true;
                                    vertNotOnTheLine = vertices[(vert + 2) % 3]; // other point is prev
                                }

                                if (isNodeOnTheLine)
                                {
                                    Vector3 pushAwayDirNorm = vertNotOnTheLine - VectorMath.ClosestPointOnLine(funnelPoint, nextFunnelPoint, vertNotOnTheLine);
                                    pushAwayDirNorm.y = 0f;
                                    pushAwayDirNorm.Normalize();

                                    // add a new point to the funnel path which is offset at a right angle from triangle line which is coincident with the funnel path
                                    Vector3 lineStart       = funnelPoint + ((nextFunnelPoint - funnelPoint) * 0.25f);
                                    Vector3 firstPointToAdd = lineStart + pushAwayDirNorm * obstaclePadding;
                                    float   maxLineLen      = CalculateMaxLineLengthXZ(lineStart, firstPointToAdd, nextFunnelPoint, vertNotOnTheLine, vertices[vert]);
                                    firstPointToAdd = lineStart + pushAwayDirNorm * maxLineLen;
                                    AddPadPointToFunnelPath(ref funnelPath, ref point, ref hasPointBeenRemoved, firstPointToAdd);

                                    // add another point to the funnel path which is offset at a right angle from triangle line which is coincident with the funnel path
                                    lineStart = funnelPoint + ((nextFunnelPoint - funnelPoint) * 0.75f);
                                    Vector3 secondPointToAdd = lineStart + pushAwayDirNorm * obstaclePadding;
                                    maxLineLen       = CalculateMaxLineLengthXZ(lineStart, secondPointToAdd, nextFunnelPoint, vertNotOnTheLine, vertices[vert]);
                                    secondPointToAdd = lineStart + pushAwayDirNorm * maxLineLen;
                                    AddPadPointToFunnelPath(ref funnelPath, ref point, ref hasPointBeenRemoved, secondPointToAdd);
                                }
                            }

                            // if the node did not have an edge on the funnel path, let's just offset from the single triangle vertex on the funnel path
                            if (!isNodeOnTheLine)
                            {
                                Vector3 toPrevVert = (vertices[(vert + 2) % 3] - vertices[vert]);
                                Vector3 toNextVert = (vertices[(vert + 1) % 3] - vertices[vert]);

                                // calculate a line between the two triangle edges and offset a point on that line
                                Vector3 newNavPoint = Vector3.Lerp(vertices[vert] + toPrevVert.normalized, vertices[vert] + toNextVert.normalized, 0.5f);
                                float   maxLength   = CalculateMaxLineLengthXZ(vertices[vert], newNavPoint, vertices[(vert + 1) % 3], vertices[(vert + 2) % 3]);
                                Vector3 dirNorm     = (newNavPoint - vertices[vert]);
                                dirNorm.y   = 0f;
                                newNavPoint = vertices[vert] + dirNorm.normalized * Mathf.Min(obstaclePadding, maxLength);
                                AddPadPointToFunnelPath(ref funnelPath, ref point, ref hasPointBeenRemoved, newNavPoint);
                            }
                            startNode = node;
                            break;
                        }
                    }
                }
            }
        }