示例#1
0
        /// <summary>
        /// Evaluate the raycast results of a single ray from the RayPerceptionInput.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="rayIndex"></param>
        /// <param name="debugRayOut"></param>
        /// <returns></returns>
        internal static RayPerceptionOutput.RayOutput PerceiveSingleRay(
            RayPerceptionInput input,
            int rayIndex,
            out DebugDisplayInfo.RayInfo debugRayOut
            )
        {
            var unscaledRayLength  = input.RayLength;
            var unscaledCastRadius = input.CastRadius;

            var extents            = input.RayExtents(rayIndex);
            var startPositionWorld = extents.StartPositionWorld;
            var endPositionWorld   = extents.EndPositionWorld;

            var rayDirection = endPositionWorld - startPositionWorld;
            // If there is non-unity scale, |rayDirection| will be different from rayLength.
            // We want to use this transformed ray length for determining cast length, hit fraction etc.
            // We also it to scale up or down the sphere or circle radii
            var scaledRayLength = rayDirection.magnitude;
            // Avoid 0/0 if unscaledRayLength is 0
            var scaledCastRadius = unscaledRayLength > 0 ?
                                   unscaledCastRadius * scaledRayLength / unscaledRayLength :
                                   unscaledCastRadius;

            // Do the cast and assign the hit information for each detectable tag.
            bool       castHit;
            float      hitFraction;
            GameObject hitObject;

            if (input.CastType == RayPerceptionCastType.Cast3D)
            {
                RaycastHit rayHit;
                if (scaledCastRadius > 0f)
                {
                    castHit = Physics.SphereCast(startPositionWorld, scaledCastRadius, rayDirection, out rayHit,
                                                 scaledRayLength, input.LayerMask);
                }
                else
                {
                    castHit = Physics.Raycast(startPositionWorld, rayDirection, out rayHit,
                                              scaledRayLength, input.LayerMask);
                }

                // If scaledRayLength is 0, we still could have a hit with sphere casts (maybe?).
                // To avoid 0/0, set the fraction to 0.
                hitFraction = castHit ? (scaledRayLength > 0 ? rayHit.distance / scaledRayLength : 0.0f) : 1.0f;
                hitObject   = castHit ? rayHit.collider.gameObject : null;
            }
            else
            {
                RaycastHit2D rayHit;
                if (scaledCastRadius > 0f)
                {
                    rayHit = Physics2D.CircleCast(startPositionWorld, scaledCastRadius, rayDirection,
                                                  scaledRayLength, input.LayerMask);
                }
                else
                {
                    rayHit = Physics2D.Raycast(startPositionWorld, rayDirection, scaledRayLength, input.LayerMask);
                }

                castHit     = rayHit;
                hitFraction = castHit ? rayHit.fraction : 1.0f;
                hitObject   = castHit ? rayHit.collider.gameObject : null;
            }

            var rayOutput = new RayPerceptionOutput.RayOutput
            {
                HasHit          = castHit,
                HitFraction     = hitFraction,
                HitTaggedObject = false,
                HitTagIndex     = -1,
                HitGameObject   = hitObject
            };

            if (castHit)
            {
                // Find the index of the tag of the object that was hit.
                var numTags = input.DetectableTags?.Count ?? 0;
                for (var i = 0; i < numTags; i++)
                {
                    var tagsEqual = false;
                    try
                    {
                        var tag = input.DetectableTags[i];
                        if (!string.IsNullOrEmpty(tag))
                        {
                            tagsEqual = hitObject.CompareTag(tag);
                        }
                    }
                    catch (UnityException e)
                    {
                        // If the tag is null, empty, or not a valid tag, just ignore it.
                    }

                    if (tagsEqual)
                    {
                        rayOutput.HitTaggedObject = true;
                        rayOutput.HitTagIndex     = i;
                        break;
                    }
                }
            }

            debugRayOut.worldStart = startPositionWorld;
            debugRayOut.worldEnd   = endPositionWorld;
            debugRayOut.rayOutput  = rayOutput;
            debugRayOut.castRadius = scaledCastRadius;

            return(rayOutput);
        }
        /// <summary>
        /// Evaluate the raycast results of a single ray from the RayPerceptionInput.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="rayIndex"></param>
        /// <param name="debugRayOut"></param>
        /// <returns></returns>
        internal static RayPerceptionOutput.RayOutput PerceiveSingleRay(
            RayPerceptionInput input,
            int rayIndex,
            out DebugDisplayInfo.RayInfo debugRayOut
            )
        {
            var unscaledRayLength  = input.RayLength;
            var unscaledCastRadius = input.CastRadius;

            var extents            = input.RayExtents(rayIndex);
            var startPositionWorld = extents.StartPositionWorld;
            var endPositionWorld   = extents.EndPositionWorld;

            var rayDirection = endPositionWorld - startPositionWorld;
            // If there is non-unity scale, |rayDirection| will be different from rayLength.
            // We want to use this transformed ray length for determining cast length, hit fraction etc.
            // We also it to scale up or down the sphere or circle radii
            var scaledRayLength = rayDirection.magnitude;
            // Avoid 0/0 if unscaledRayLength is 0
            var scaledCastRadius = unscaledRayLength > 0 ?
                                   unscaledCastRadius * scaledRayLength / unscaledRayLength :
                                   unscaledCastRadius;

            // Do the cast and assign the hit information for each detectable tag.
            bool       castHit;
            float      hitFraction;
            GameObject hitObject;
            RaycastHit rayHit = new RaycastHit();;

            if (input.CastType == RayPerceptionCastType.Cast3D)
            {
                if (scaledCastRadius > 0f)
                {
                    // castHit = Physics.SphereCast(startPositionWorld, scaledCastRadius, rayDirection, out rayHit,
                    //     scaledRayLength, input.LayerMask);
                    System.Random rnd = new System.Random();
                    castHit = (rnd.Next(2) == 0);
                }
                else
                {
                    // castHit = Physics.Raycast(startPositionWorld, rayDirection, out rayHit,
                    //     scaledRayLength, input.LayerMask);
                    System.Random rnd = new System.Random();
                    castHit = (rnd.Next(2) == 0);
                }

                // If scaledRayLength is 0, we still could have a hit with sphere casts (maybe?).
                // To avoid 0/0, set the fraction to 0.
                hitFraction = castHit ? (scaledRayLength > 0 ? rayHit.distance / scaledRayLength : 0.0f) : 1.0f;
                // hitObject = castHit ? rayHit.collider.gameObject : null;
            }
            else
            {
                RaycastHit2D ray2Hit;
                if (scaledCastRadius > 0f)
                {
                    ray2Hit = Physics2D.CircleCast(startPositionWorld, scaledCastRadius, rayDirection,
                                                   scaledRayLength, input.LayerMask);
                }
                else
                {
                    ray2Hit = Physics2D.Raycast(startPositionWorld, rayDirection, scaledRayLength, input.LayerMask);
                }

                castHit     = ray2Hit;
                hitFraction = castHit ? ray2Hit.fraction : 1.0f;
                //  hitObject = castHit ? ray2Hit.collider.gameObject : null;
            }

            var rayOutput = new RayPerceptionOutput.RayOutput
            {
                HasHit          = castHit,
                HitFraction     = hitFraction,
                HitTaggedObject = false,
                HitTagIndex     = -1
            };

            if (castHit)
            {
                // Find the index of the tag of the object that was hit.
                for (var i = 0; i < input.DetectableTags.Count; i++)
                {
                    //   if (hitObject.CompareTag(input.DetectableTags[i]))
                    //   {
                    rayOutput.HitTaggedObject = true;
                    rayOutput.HitTagIndex     = i;
                    break;
                    //  }
                }
            }

            debugRayOut.worldStart = startPositionWorld;
            debugRayOut.worldEnd   = endPositionWorld;
            debugRayOut.rayOutput  = rayOutput;
            debugRayOut.castRadius = scaledCastRadius;

            return(rayOutput);
        }