How can I apply damage based on a grenade explosion, but test whether the objects are behind cover so they are not damaged even within the explosion radius?

I was wondering if it is possible to have a object shoot out rays in all directions. I want this for a grenade, as i want it so when the grenade blows up it shoots out rays in all directions, and if a ray hits something it will apply damage. I want to do it with ray casting because i want it so if the player is behind cover they will not get hurt, unlike if i spawned a trigger to check for collisions with player, as that would go threw walls. IF you got a better way of doing it please tell me otherwise help me the best you can. Also, can you have it set so it will calculate the length of the ray? U would like that as it would make it easier to apply damage, if the player is on top of the grenade it is instant death, within 1 meter is half health, and within 5 meters is 25% of the health. I would set the ray to be about 6 meters long if i could calculate the length of it.

I would do these calculations in the opposite order:

  1. find all damagable objects within the radius
  2. cast a ray from the grenade to each found object, to test whether they are shielded

For more information, see this answer which discusses how to apply damage which falls off within a certain blast radius, and just add the raycast test to it, to check for cover.

function AreaDamageEnemies(location : Vector3, radius : float , damage : float )
{
    var objectsInRange : Collider[] = Physics.OverlapSphere(location, radius);
    for (var col : Collider in objectsInRange)
    {
        var enemy : Enemy = col.GetComponent(Enemy);
        if (enemy != null)
        {
            // test if enemy is exposed to blast, or behind cover:
            var hit : RaycastHit;
            var exposed = false;
            if (Physics.Raycast (location, (enemy.transform.position-location), hit)) {
                exposed = (hit.collider = enemyCollider);
            }

            if (exposed) {
                // Damage Enemy! with a linear falloff of damage amount
                var proximity : float = (location - enemy.transform.position).magnitude;
                var effect : float = 1 - (proximity / radius);
                enemy.ApplyDamage(damage * effect);
            }
        }
    }
}

If you're using rigidbodies for your enemy objects, you could also use AddExplosionForce to add a proximity based force to push them away from the explosion centre.

If you enable the Maximize on Play button in the Game window, the Game Window will expand when you hit play and get small again when you stop. The downside to this is that you can’t see the inspector/hierarchy windows without opening them manually.

You are right in this aspect

@duck the script works well. the only problem is if a player is in front of another player. the player behind it would not take the damage.

how do i fix that?

also heres the code.

    float power = 100;
    int damage = 1;

    float radius = 100f;


    void Start()
    {

    }

    void Update()
    {

        if (Input.GetButton("Fire1"))
        {
            Explode();
        }
    }

    void Explode()
    {


        Collider[] colliders = Physics.OverlapSphere(transform.position, radius);
        Debug.Log("Count of colliders = " + colliders.Length);

     
                 foreach (Collider collider in colliders)
        {
            if (collider.tag == "brick" || collider.tag == "Player")
            {
                Debug.Log("Found brick or a player");
                Debug.Log("collider is " + collider.name);




                RaycastHit hit;

                if (Physics.Linecast(transform.position, collider.transform.position, out hit, 5) )   // collider.tag != "Player" || collider.tag != "brick")
                {
                   
                    if (hit.collider == collider)
                    {
                        Debug.Log("No obstructions");

                        if (hit.rigidbody)
                            hit.rigidbody.AddExplosionForce(power, transform.position, radius, 50f);
                     


                    }
                }

         
            }
        }
    }