Search code examples
c#unity-game-enginegame-physics

My Raycast does not seem to have any range - only detects objects placed next to emitting gameobject


I'm using the following code (from:https://gist.github.com/valryon/566c02f3c5808dcd9968) to generate a 2D laser in my game. The laser has a start, middle and end parts. That make up the laser and are childed to the parent gameobject.

public class LaserScript : MonoBehaviour
{
    [Header("Laser pieces")]
    public GameObject laserStart;
    public GameObject laserMiddle;
    public GameObject laserEnd;

    private GameObject start;
    private GameObject middle;
    private GameObject end;

    void Update()
    {
        // Create the laser start from the prefab
        if (start == null)
        {
            start = Instantiate(laserStart) as GameObject;
            start.transform.parent = this.transform;
            start.transform.localPosition = Vector2.zero;
        }

        // Laser middle
        if (middle == null)
        {
            middle = Instantiate(laserMiddle) as GameObject;
            middle.transform.parent = this.transform;
            middle.transform.localPosition = Vector2.zero;
        }

        // Define an "infinite" size, not too big but enough to go off screen
        float maxLaserSize = 200f;
        float currentLaserSize = maxLaserSize;

        // Raycast at the right as our sprite has been design for that
        Vector2 laserDirection = this.transform.right;
        RaycastHit2D hit = Physics2D.Raycast(this.transform.position, laserDirection, maxLaserSize);
        Debug.Log(hit.collider.tag);
        if (hit.collider.tag == "Enemy")
        {
            // We touched something!

            // -- Get the laser length
            currentLaserSize = Vector2.Distance(hit.point, this.transform.position);

            // -- Create the end sprite
            if (end == null)
            {
                end = Instantiate(laserEnd) as GameObject;
                end.transform.parent = this.transform;
                end.transform.localPosition = Vector2.zero;
            }
        }
        else
        {
            // Nothing hit
            // -- No more end
            if (end != null) Destroy(end);
        }

        // Place things
        // -- Gather some data
        float startSpriteWidth = start.GetComponent<Renderer>().bounds.size.x;
        float endSpriteWidth = 0f;
        if (end != null) endSpriteWidth = end.GetComponent<Renderer>().bounds.size.x;

        // -- the middle is after start and, as it has a center pivot, have a size of half the laser (minus start and end)
        middle.transform.localScale = new Vector3(currentLaserSize - startSpriteWidth, middle.transform.localScale.y, middle.transform.localScale.z);
        middle.transform.localPosition = new Vector2((currentLaserSize / 2f), 0f);

        // End?
        if (end != null)
        {
            end.transform.localPosition = new Vector2(currentLaserSize, 0f);
        }

    }
}

The script should have the effect shown in the gif below:

enter image description here

But my laser only detects an object when it is right infront of it, when the start part of the laser actually touches the enemy only then does the Debug.Log report Enemy other wise its unknown.

I get the desired effect as shown in gif, but my raycast does not detect any enemy until the player shooting the laser stands right next to the enemy.

What might be the reason for this?

Thanks


Solution

  • Physics.Raycast() returns a boolean, not a RaycastHit.

    Use the following syntax to return the collider's information :

    public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance);

    This code checks if the Raycast hit something and stores the collider's information in hit:

    RaycastHit hit;
    
    if(Physics.Raycast(transform.position, laserDirection, out hit, maxLaserSize))
    {
        Debug.Log(hit.collider.tag);
    }