Search code examples
c#unity-game-engineobject-detectiongame-physicsraycasting

Raycast detects all object, but not all objects take damage


When the player presses Q, it creates a ball. The more time you press Q, the ball gets bigger and bigger.

This is the problem: If the ball is small, after the explosion, raycast detect nearby enemies and deal damage (if they are inside the explosion radius), but, as the ball gets bigger and bigger, raycast detect enemies but doesn't deal any damage to them. (I use spherecast and then I send a raycast to every object that is inside the radius)

Small ball explosion
Small ball explosion, detects all of the enemies and deals damage to some of them
big ball explosion
big ball explosion, detects all of the enemies and deals damage to none of them

New info: Here you can see radius before explision. After explosion 4 of enemies got detected, but only 2 of them got damaged

using UnityEngine;

public class BULLET : MonoBehaviour
{

    [SerializeField] float countDown;
    [SerializeField] int Maxhits = 25;
    bool destroyy = false;
    public float Radius = 10f;
    //[SerializeField] LayerMask HitLayer;
    public float explosiveForce;
    [SerializeField] LayerMask BlockExplo;
    private Collider[] Hits;
    bool wallHit = false;
    [SerializeField] float x, y, z;
    [SerializeField] GameObject posRay;
    [SerializeField] GameObject Ps_Explose;
    [SerializeField] float MaxDamage;
    [SerializeField] float MinDamage;

    private void Start()
    {
        Hits = new Collider[Maxhits]
    }

    private void FixedUpdate()
    {
        countDown -= Time.deltaTime;

        if (destroyy || countDown <= 0)
        {
            int hits = Physics.OverlapSphereNonAlloc(posRay.transform.position, Radius, Hits);

            GameObject PS = Instantiate(Ps_Explose, transform.position, gameObject.transform.rotation);
            PS.transform.localScale = gameObject.transform.localScale * 1.5f;
            // print("" + transform.position);

            for (int i = 0; i < hits; i++)
            {
                RaycastHit hit;
                if (Physics.Raycast(posRay.transform.position, Hits[i].transform.position - transform.position))
                {
                    if (Hits[i].TryGetComponent<Rigidbody>(out Rigidbody rigidbody))
                    {
                        float distance = Vector3.Distance(posRay.transform.position, Hits[i].transform.position);

                        if (Physics.Raycast(posRay.transform.position + new Vector3(x, y, z), (Hits[i].transform.position - transform.position), out hit))
                        {
                            Debug.DrawLine(posRay.transform.position + new Vector3(x, y, z), (Hits[i].transform.position), Color.red);

                            if (hit.transform.tag != "Walls")
                            {
                                print("No wall");
                                rigidbody.AddExplosionForce(explosiveForce, transform.position, Radius);
                                if (hit.transform.tag == "Enemy")
                                    hit.transform.GetComponent<EnemyHp>().enemyHp -= Mathf.FloorToInt(Mathf.Lerp(MaxDamage, MinDamage, distance / Radius));
                            }
                            else
                            {
                                print("WALLLLL " + hit.transform.position + hit.transform.name);
                                //return;
                            }
                        }
                    }
                }
            }

            Destroy(gameObject);
        }
    }


    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.transform.tag == ("Walls") || other.gameObject.transform.tag == "Enemy")
        {
            destroyy = true;
        }
    }


    private void OnDrawGizmos()
    {
        Gizmos.DrawSphere(transform.position, Radius);
    }
}

Solution

  • Okay i found out how i can do it to work. This part of code should be changed into

      if (Hits[i].TryGetComponent<Rigidbody>(out Rigidbody rigidbody))
                {
                    float distance = Vector3.Distance(posRay.transform.position, Hits[i].transform.position);
    
    
    
    
                    if (Physics.Raycast(posRay.transform.position + new Vector3(x, y, z), (Hits[i].transform.position - transform.position), out hit))
                    {
                        Debug.DrawLine(posRay.transform.position + new Vector3(x, y, z), (Hits[i].transform.position), Color.red);
    
                        if (hit.transform.tag != "Walls")
                        {
    
                            print("No wall");
                            rigidbody.AddExplosionForce(explosiveForce, transform.position, Radius);
                            if (hit.transform.tag == "Enemy")
                                hit.transform.GetComponent<EnemyHp>().enemyHp -= Mathf.FloorToInt(Mathf.Lerp(MaxDamage, MinDamage, distance / Radius));
                        }
                        else
                        {
    
                            print("WALLLLL " + hit.transform.position + hit.transform.name);
                            //return;
                        }
    
    
    
                        //  }
                    }
    
                }
    

    This one

      if (Hits[i].TryGetComponent<Rigidbody>(out Rigidbody rigidbody))
                    {
                        float distance = Vector3.Distance(posRay.transform.position, Hits[i].transform.position);
    
    
    
    
                        if (Physics.Raycast(posRay.transform.position , (Hits[i].transform.position - transform.position).normalized, out hit))
                        {
                            Debug.DrawLine(posRay.transform.position, (Hits[i].transform.position ), Color.red);
    
                        
                                if (Hits[i].transform.CompareTag("Enemy"))
                            {
                                 
                            if (Physics.Raycast(Hits[i].transform.position,  (transform.position - Hits[i].transform.position).normalized, out hit))
                                if(hit.transform.tag != "Walls")
                                {
                                    rigidbody.AddExplosionForce(explosiveForce, transform.position, Radius);
                                    Hits[i].transform.GetComponent<EnemyHp>().enemyHp -= Mathf.FloorToInt(Mathf.Lerp(MaxDamage, MinDamage, distance / Radius));
                                }
                              
                            }
                                  
                         
    
    
    
                            //  }
                        }
    
                    }