Question by
Ovicior · May 09, 2016 at 11:21 PM ·
c#raycast2d-platformer2d-physicsraycasthit2d
One 2D Raycast Not Stopping Even Though Others Do?
So, I've got some (kinda) working code for collision detection. Unfortunately, one of the rays seems to keep going past the collider, even though the others don't. Why would this individual act differently? Can anyone help? https://i.gyazo.com/3348630296886ffc4781eceeb97ffbd2.gif
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(BoxCollider2D))]
public class Controller2D : MonoBehaviour
{
public LayerMask collisionMask;
const float skinWidth = .015f;
public int horizontalRayCount = 4;
public int verticalRayCount = 4;
float horizontalRaySpacing;
float verticalRaySpacing;
BoxCollider2D collider;
RaycastOrigins raycastOrigins;
void Start()
{
collider = GetComponent<BoxCollider2D>();
CalculateRaySpacing();
}
public void Move(Vector3 velocity)
{
UpdateRaycastOrigins();
if (velocity.x != 0)
{
HorizontalCollisions(ref velocity);
}
if (velocity.y != 0)
{
VerticalCollisions(ref velocity);
}
transform.Translate(velocity);
}
void HorizontalCollisions(ref Vector3 velocity)
{
float directionX = Mathf.Sign(velocity.x);
float rayLength = Mathf.Abs(velocity.x) + skinWidth;
for (int i = 0; i < horizontalRayCount; i++)
{
Vector2 rayOrigin = (directionX == -1) ? raycastOrigins.bottomLeft : raycastOrigins.bottomRight;
rayOrigin += Vector2.up * (horizontalRaySpacing * i);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength, Color.red);
if (hit)
{
velocity.x = (hit.distance - skinWidth) * directionX;
rayLength = hit.distance;
}
}
}
void VerticalCollisions(ref Vector3 velocity)
{
float directionY = Mathf.Sign(velocity.y);
float rayLength = Mathf.Abs(velocity.y) + skinWidth;
for (int i = 0; i < verticalRayCount; i++)
{
Vector2 rayOrigin = (directionY == -1) ? raycastOrigins.bottomLeft : raycastOrigins.topLeft;
rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength, Color.red);
if (hit)
{
velocity.y = (hit.distance - skinWidth) * directionY;
rayLength = hit.distance;
}
}
}
void UpdateRaycastOrigins()
{
Bounds bounds = collider.bounds;
bounds.Expand(skinWidth * -2);
raycastOrigins.bottomLeft = new Vector2(bounds.min.x, bounds.min.y);
raycastOrigins.bottomRight = new Vector2(bounds.max.x, bounds.min.y);
raycastOrigins.topLeft = new Vector2(bounds.min.x, bounds.max.y);
raycastOrigins.topRight = new Vector2(bounds.max.x, bounds.max.y);
}
void CalculateRaySpacing()
{
Bounds bounds = collider.bounds;
bounds.Expand(skinWidth * -2);
horizontalRayCount = Mathf.Clamp(horizontalRayCount, 2, int.MaxValue);
verticalRayCount = Mathf.Clamp(verticalRayCount, 2, int.MaxValue);
horizontalRaySpacing = bounds.size.y / (horizontalRayCount - 1);
verticalRaySpacing = bounds.size.x / (verticalRayCount - 1);
}
struct RaycastOrigins
{
public Vector2 topLeft, topRight;
public Vector2 bottomLeft, bottomRight;
}
}
Comment