MThiele
MThiele

Reputation: 387

Raycast2D hits only one side of Collider

I want to make sure that various objects moving at high speed cannot pass through walls or other objects. My thought process was to check via Raycast if a collision has occurred between two moments of movement.

So the script should remember the previous position and check via Raycast for collisions between previous and current position.

If a collision has occurred, the object should be positioned at the meeting point and moved slightly in the direction of the previous position.

My problem is that works outside the map not inside. If I go from inside to outside, I can go through the walls. From outside to inside not.

Obviously I have misunderstood something regarding the application with raycasts.

MapLayout with Walls

    using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObsticalControll : MonoBehaviour
{

    private Vector3 positionBefore;
    public LayerMask collisionLayer = 9;
    private Vector3 lastHit = new Vector3(0, 0, -20);
    // Start is called before the first frame update
    void Start()
    {
        positionBefore = transform.position;


    }

    private void OnDrawGizmos()
    {
        Gizmos.DrawCube(lastHit, new Vector3(.2f,.2f,.2f));
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 curruentMovement = transform.position;
        Vector2 dVector = (Vector2)transform.position - (Vector2)positionBefore;
        float distance = Vector2.Distance((Vector2)positionBefore, (Vector2)curruentMovement);
        RaycastHit2D[] hits = Physics2D.RaycastAll((Vector2)positionBefore, dVector, distance, collisionLayer);

        if(hits.Length > 0)
        {
            Debug.Log(hits.Length);
            for (int i = hits.Length -1 ; i >= 0 ; i--)
            {
                RaycastHit2D hit = hits[i];
                if (hit.collider != null)
                {
                    Debug.Log("hit");
                    lastHit.x = hit.point.x;
                    lastHit.y = hit.point.y;      
                    Vector3 resetPos = new Vector3(hit.point.x, hit.point.y, transform.position.z) + positionBefore.normalized * 0.1f;
                    transform.position = new Vector3(resetPos.x, resetPos.y, transform.position.z);
                }
            }
                
           
        }



        positionBefore = transform.position;
    }
}

Upvotes: 0

Views: 639

Answers (2)

Legendary_zotar
Legendary_zotar

Reputation: 51

However, I am still wondering about the collision behavior of my raycast script. That would be surely interesting, if you want to calculate shots or similar via raycast

Alright, so your initial idea was to check if a collision had occurred, By checking its current position and its previous position. And checking if anything is between them, that means a collision has occurred. And you would teleport it back to where it was suppose to have hit.

A better way todo this would be to check where the GameObject would be in the next frame, by raycasting ahead of it, by the distance that it will travel. If it does hit something that means that within the next frame, it would have collided with it. So you could stop it at the collision hit point, and get what it has hit. (This means you wouldn't have to teleport it back, So there wouldn't be a frame where it goes through then goes back)

Almost the same idea but slightly less complicated.

Problem would be that if another object were to appear between them within the next frame aswell, it could not account for that. Which is where the rigidbody.movePosition shines, And with OnCollisionEnter you can detect when and what it collided with correctly. Aswell as without the need to teleport it back

Upvotes: 0

Legendary_zotar
Legendary_zotar

Reputation: 51

Theres a better way to deal with this that unity has built in. Assuming the object thats moving at a high speed has a RigidBody(2d in your case) you can set its Collision Detection to Continuous instead of Discrete.

enter image description here

This will help collisions with high speed collision, assuming that its moving at high speed and the wall is not moving.

If for some reason you cannot apply this to your scenario, Ill try to help with the raycast solution.

Upvotes: 1

Related Questions