0
\$\begingroup\$

As the title suggests I would like to destroy the game object that my raycast hits. I have a movement script attached to my player object. A raycast2d is continuously shot downward, and when it collides with an object on the enemy layer it registers the collision and returns its value. What I want to do now is destroy that object, however when I use the destroy game object command, it destroys the gameObject that the script is attached to, as one may expect. How can I destroy this enemy object, which the script is not attached to.

This is the current code that I am using:

bool HitEnemy()
{
    Vector2 position = transform.position;
    Vector2 direction = Vector2.down;
    float distance = 2.0f;
    
    
    RaycastHit2D hit = Physics2D.Raycast(position, direction, distance, enemyLayer);
    if (hit.collider != null) 
    {
        return true;
    }

    return false; 

    
}

I will be doing something similar, where my enemy shoots a horizontal ray, which will then kill the player character. How can I reference these 2?

I am relatively new to C# coding, so any help will be greatly appreciated.

\$\endgroup\$
1
  • \$\begingroup\$ Just updated the sentence I botched. Will add my code tonight when I get home. \$\endgroup\$
    – TBG
    Sep 29, 2021 at 12:04

2 Answers 2

2
\$\begingroup\$

Here is a demo that accomplishes what you are asking.

First, the set up -- the scene consists of a player sprite and 3 enemy sprites.

set up

The enemy sprites are assigned to the Enemy Layer. Each has a Collider2D component.

Enemy -- Inspector

The Player sprite is similar, but it also has a custom component attached and of course is not assigned to the Enemy layer.

Player -- Inspector

On to the script. First we declare a couple of handy variables with sensible default values that we can adjust later in the inspector:

    [SerializeField] private Vector2 m_RayDirection = Vector2.down;
    [SerializeField] private float m_RayRange = 4;

On Start, we let LayerMask do the bit-twiddling to calculate the correct mask value:

 int enemyLayer;
    void Start()
    {
       enemyLayer = LayerMask.GetMask("Enemy");
    } 

The fun happens in Update. First, we'll move our player from side to side, simply for demo purposes. Mathf.PingPong() is a simple way to do this.

transform.position = new Vector3(Mathf.PingPong(Time.time, 4f) - 2.0f, 0, 0);

Now, we test for a hit using the parameters we've assembled:

   RaycastHit2D hit;
   hit = Physics2D.Raycast(transform.position, m_RayDirection, m_RayRange, enemyLayer);
        if (hit)
        {
            Debug.Log("Hit " + hit.collider.name);
            //You could do other stuff here, like instantiate particles or play sounds...

            //Destroy the enemy GO:
            Destroy(hit.collider.gameObject);
        }

Here's the entire script:

using UnityEngine;

public class Player_X : MonoBehaviour
{

    [SerializeField] private Vector2 m_RayDirection = Vector2.down;
    [SerializeField] private float m_RayRange = 4;

    int enemyLayer;
    void Start()
    {
       enemyLayer = LayerMask.GetMask("Enemy");
    }

    RaycastHit2D hit;
    void Update()
    {
        //Move the Player back and forth across the screen, for demo
        transform.position = new Vector3(Mathf.PingPong(Time.time, 4f) - 2.0f, 0, 0);

        hit = Physics2D.Raycast(transform.position, m_RayDirection, m_RayRange, enemyLayer);
        if (hit)
        {
            //Draw a debug ray to see what's happening
            Debug.DrawRay(transform.position, m_RayDirection * m_RayRange, Color.green,.5f);

            Debug.Log("Hit " + hit.collider.name);
            //You could do other stuff here, like instantiate particles or play sounds...

            //Destroy the enemy GO:
            Destroy(hit.collider.gameObject);
        }
    }
}
\$\endgroup\$
8
  • \$\begingroup\$ THANK YOU SO MUCH! I have been so stuck on this, and your reply is so well formatted and informative. \$\endgroup\$
    – TBG
    Oct 2, 2021 at 19:41
  • \$\begingroup\$ You're welcome. I'm glad you found it helpful. \$\endgroup\$ Oct 2, 2021 at 19:55
  • \$\begingroup\$ One final question, when attempting to use Debug.DrawRay and assign a color I get the error that 'color does not exist in the current context'. Any possible insight? \$\endgroup\$
    – TBG
    Oct 2, 2021 at 19:57
  • \$\begingroup\$ 1) what makes you say the ray is casting too far? Can you share your set-up? 2) can you share the relevant code that is drawing the debug ray? \$\endgroup\$ Oct 2, 2021 at 20:00
  • \$\begingroup\$ The Ray Range being set at 4 made contact with the enemy sprite, before the player sprite was close enough. I just edited it in inspector, and it worked perfectly. \$\endgroup\$
    – TBG
    Oct 2, 2021 at 20:01
2
\$\begingroup\$

I think you could try something like this:

RaycastHit hit;
if (Physics2D.Raycast(ray, out hit)
{
    Destroy(hit.gameobject);
}
\$\endgroup\$
2
  • \$\begingroup\$ Thank you. I will give this a try ASAP. \$\endgroup\$
    – TBG
    Sep 27, 2021 at 4:36
  • \$\begingroup\$ Physics.Raycast() works in 3D, its 2D counterpart is Physics2D.Raycast() \$\endgroup\$
    – liggiorgio
    Sep 27, 2021 at 9:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .