Jump to content
  • Advertisement
Sign in to follow this  
Ovicior

Unity Unity Raycast Being Weird

This topic is 795 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been working on a 2D raycasting system, and have an odd glitch-like thing going on. When the rays fire off and collide with something, all of the rays work perfectly well except for one. This ray keeps pushing past the collider and, in turn, is constantly changing the player's y-values.

 

 

Can anyone see a fix?

 

 

3348630296886ffc4781eceeb97ffbd2.gif

 

 

 

Code:

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;
    }

}

Share this post


Link to post
Share on other sites
Advertisement

While I don't immediately see the error, you could try doing the Debug.Draw in different colors based on i to see if it's always the same ray that's messing up, and then Debug print values for that specific ray and see if anything becomes apparent.

 

In the VerticalCollisions I was slightly surprised to see velocity.x used, but I guess it makes sense for movement collision? (Although HorizontalCollisions doesn't do the equivalent.)

Share this post


Link to post
Share on other sites

your'e probably experiencing an unusual case with the raycast caused by the corner.Try separating the box and the rectangular stage into separate pieces to see if that helps..

Share this post


Link to post
Share on other sites

your'e probably experiencing an unusual case with the raycast caused by the corner.Try separating the box and the rectangular stage into separate pieces to see if that helps..

They both start separated, with the square at the top. The gravity causes the square to land on the rectangle.

Share this post


Link to post
Share on other sites

While I don't immediately see the error, you could try doing the Debug.Draw in different colors based on i to see if it's always the same ray that's messing up, and then Debug print values for that specific ray and see if anything becomes apparent.

 

In the VerticalCollisions I was slightly surprised to see velocity.x used, but I guess it makes sense for movement collision? (Although HorizontalCollisions doesn't do the equivalent.)

Interestingly, the same ray is always changing when it shouldn't be. I changed the color and it still occurred. If the player falls from high enough, the rays doesn't seem to change its values. If the player lands close to the platform, the stray ray changes the value of the player by tiny amounts.

Share this post


Link to post
Share on other sites

 

While I don't immediately see the error, you could try doing the Debug.Draw in different colors based on i to see if it's always the same ray that's messing up, and then Debug print values for that specific ray and see if anything becomes apparent.

 

In the VerticalCollisions I was slightly surprised to see velocity.x used, but I guess it makes sense for movement collision? (Although HorizontalCollisions doesn't do the equivalent.)

Interestingly, the same ray is always changing when it shouldn't be. I changed the color and it still occurred. If the player falls from high enough, the rays doesn't seem to change its values. If the player lands close to the platform, the stray ray changes the value of the player by tiny amounts.

 

FIGURED IT OUT!

 

 

Turns out the gravity was accumulating and forcing the ray down. Just had to set gravity to 0 in the update function.

Share this post


Link to post
Share on other sites

If the rigidbody component is attached, you can turn off the gravity for the object there as well.  (If not, you must be doing custom gravity)

Share this post


Link to post
Share on other sites

If the rigidbody component is attached, you can turn off the gravity for the object there as well.  (If not, you must be doing custom gravity)

No, I am not using the rigidbody. I have custom gravity.

 

 

Thanks anyway :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!