/// <summary> /// Performs ray with gameobject layer. /// </summary> /// <returns>If hit object and distance to objects</returns> public NewPoint PerformRays(Vector2 velocity, RayTypes rays, ref List <RaycastHit2D> raycastHits) { raycastHits.Clear(); const float CompareZero = 0.00001f; var hitCollider = false; Vector2 distanceToEdge = Vector2.zero; if (Mathf.Abs(velocity.x) > CompareZero) { var checkAxis = CheckCollisionAxis(velocity, AxisDirection.Horizontal, rays, layermask, ref raycastHits); if (checkAxis.HasPoint) { hitCollider = true; distanceToEdge = checkAxis.Point; } } if (Mathf.Abs(velocity.y) > CompareZero) { var checkAxis = CheckCollisionAxis(velocity, AxisDirection.Vertical, rays, layermask, ref raycastHits); if (checkAxis.HasPoint) { hitCollider = true; distanceToEdge += checkAxis.Point; } } if (hitCollider) { return(new NewPoint(distanceToEdge)); } else { return(new NewPoint(false)); } }
private NewPoint CheckCollisionAxis(Vector2 velocity, AxisDirection axisDirection, RayTypes rayTypes, LayerMask layerMask, ref List <RaycastHit2D> raycastHits) { // percentage of the way to the edge where the ray should shoot const float DistanceToEdgeMultiplier = 0.75f; // If Vertical float axisVelocity = velocity.y; Vector2 direction = new Vector2(0, axisVelocity); float forwardDistance = objectExtents.y; float sideDistance = objectExtents.x * DistanceToEdgeMultiplier; Vector2 directionToEdge = Vector2.right; // If Horizontal if (axisDirection == AxisDirection.Horizontal) { directionToEdge = Vector2.up; axisVelocity = velocity.x; direction = new Vector2(axisVelocity, 0); forwardDistance = objectExtents.x; sideDistance = objectExtents.y * DistanceToEdgeMultiplier; } var rayDistance = Mathf.Abs(axisVelocity) + forwardDistance; direction.Normalize(); bool hitFirstPoint = false; bool hitSecondPoint = false; bool hitThirdPoint = false; if (rayTypes.HasFlag(RayTypes.EdgeRays)) { directionToEdge *= sideDistance; var firstPoint = currentPosition + directionToEdge; var secondPoint = currentPosition - directionToEdge; #if UNITY_EDITOR var directionAndLength = direction * rayDistance; debugRays[0] = new Ray(firstPoint, directionAndLength); debugRays[1] = new Ray(secondPoint, directionAndLength); debugRays[2] = new Ray(currentPosition, directionAndLength); #endif hitFirstPoint = (Physics2D.RaycastNonAlloc(firstPoint, direction, firstHits, rayDistance, layerMask) > 0); hitSecondPoint = (Physics2D.RaycastNonAlloc(secondPoint, direction, secondHits, rayDistance, layerMask) > 0); } if (rayTypes.HasFlag(RayTypes.MiddleRay)) { hitThirdPoint = (Physics2D.RaycastNonAlloc(currentPosition, direction, thirdHits, rayDistance, layerMask) > 0); } // If hit collider if (hitFirstPoint || hitSecondPoint || hitThirdPoint) { // Find closest point var firstHit = firstHits[0]; var secondHit = secondHits[0]; var thirdHit = thirdHits[0]; float firstHitDistance = (hitFirstPoint) ? firstHit.distance : 255; float secondHitDistance = (hitSecondPoint) ? secondHit.distance : 255; float thirdHitDistance = (hitThirdPoint) ? thirdHit.distance : 255; closestHit.distance = 254; if (firstHitDistance < secondHitDistance) { closestHit = firstHit; } if (closestHit.distance >= secondHitDistance) { closestHit = secondHit; } if (closestHit.distance >= thirdHitDistance) { closestHit = thirdHit; } if (hitFirstPoint) { raycastHits.Add(firstHit); } if (hitSecondPoint) { raycastHits.Add(secondHit); } if (hitThirdPoint) { raycastHits.Add(thirdHit); } return(new NewPoint(direction * (closestHit.distance - forwardDistance))); } return(new NewPoint(false)); }