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 at 12:04
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 at 19:41
  • \$\begingroup\$ You're welcome. I'm glad you found it helpful. \$\endgroup\$ Oct 2 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 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 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 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 at 4:36
  • \$\begingroup\$ Physics.Raycast() works in 3D, its 2D counterpart is Physics2D.Raycast() \$\endgroup\$
    – liggiorgio
    Sep 27 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.