Search Unity

Explosion script: other object can't detect explosion knockback

Discussion in 'Scripting' started by billydog132, Nov 25, 2020.

  1. billydog132

    billydog132

    Joined:
    Nov 1, 2020
    Posts:
    16
    Hello, I have been working a long time on this problem but i can't figure out how to fix it.
    Here is the idea:
    I am making a FPS game, you shot arrow, throw rock at alien to kill them. (being ragdoll for 2 second than destroy gameObject).

    The thing is you can also throw bomb at alien to make them explode.
    I want the alien to detect the explosion collision and activate the dead function too.
    The problem is: the alien does get push back when the bomb explode but it can't detect if they get hit by the explosion so that they can being dead.
    It only push them backward but they are still attacking the player, they are not dead because they haven't detected if they were hit by an explosion of a bomb.


    When the player throw a bomb, it activate the Explosion.cs script (detonate()):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Explosion : MonoBehaviour
    6. {
    7.     public float power = 10.0F;
    8.     public float radius = 5.0F;
    9.     public float upForce = 1.0F;
    10.  
    11.     public IEnumerator Explode() {
    12.         ParticleSystem exp = GetComponent<ParticleSystem>();
    13.         exp.Play();
    14.         Destroy(gameObject, exp.main.duration);
    15.         yield return new WaitForSeconds(2);
    16.         gameObject.GetComponent<Renderer>().enabled = false;
    17.         gameObject.GetComponent<Rigidbody>().freezeRotation = true;
    18.         detonate();
    19.         gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
    20.         gameObject.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
    21.     }
    22.  
    23.     private void detonate()
    24.     {
    25.         Vector3 explosionPostion = gameObject.transform.position;
    26.         Collider[] colliders = Physics.OverlapSphere(explosionPostion, radius);
    27.         foreach (Collider hit in colliders)
    28.         {
    29.             Rigidbody rb = hit.GetComponent<Rigidbody>();
    30.             if (rb != null)
    31.             {
    32.                 rb.AddExplosionForce(power,explosionPostion,radius,upForce,ForceMode.Impulse);
    33.             }
    34.         }
    35.     }
    36. }
    37.  
    The alien got an script called EnnemieAI.cs:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class EnnemieAI : MonoBehaviour
    6. {
    7.     public Transform player;
    8.     public healthPlayer playerHealth;
    9.     public float distanceTriggerAggresive = 100;
    10.     public float moveSpeed = 10f;
    11.     private Rigidbody rb;
    12.     private bool isDead = false;
    13.     private bool attacking = false;
    14.  
    15.     // Start is called before the first frame update
    16.     void Start()
    17.     {
    18.         rb = this.GetComponent<Rigidbody>();
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.         float distance = Vector3.Distance (player.position, this.gameObject.transform.position);
    25.         if (!isDead)
    26.         {
    27.             if (distance <= distanceTriggerAggresive)
    28.             {
    29.                 Vector3 playerPosWithoutY = new Vector3(player.position.x,0,player.position.z);
    30.                 Vector3 pos = Vector3.MoveTowards(transform.position, playerPosWithoutY, moveSpeed * Time.fixedDeltaTime);
    31.                 rb.MovePosition(pos);
    32.                 transform.LookAt(player);
    33.             }
    34.             else if (distance > distanceTriggerAggresive)
    35.             {
    36.                 gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
    37.                 gameObject.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
    38.             }
    39.         }
    40.         else
    41.         {
    42.             Destroy(this.gameObject, 2);
    43.         }
    44.    
    45.         if (attacking)
    46.         {
    47.             attackPlayer();
    48.         }
    49.     }
    50.  
    51.     private void attackPlayer()
    52.     {
    53.  
    54.         playerHealth.getHit(0.5f);
    55.     }
    56.  
    57.     private void OnCollisionEnter(Collision collision)
    58.     {
    59.         if (collision.gameObject.name == "barreArbalete(Clone)" || collision.gameObject.name == "Comête")
    60.         {
    61.             isDead = true;
    62.             Destroy(this.gameObject, 2);
    63.         }
    64.     }
    65.  
    66.     private void OnCollisionExit(Collision collisionInfo)
    67.     {
    68.         attacking = false;
    69.     }
    70.  
    71.     private void OnTriggerEnter(Collider other)
    72.     {
    73.         if (other.gameObject.name != "Terrain")
    74.             Debug.Log(other.name);
    75.    
    76.         if (other.gameObject.name == "Joueur")
    77.         {
    78.             attacking = true;
    79.         }
    80.     }
    81.  
    82.  
    83. }
    Here the EnnemieAi script can detect if the alien gameObject got a collision by a arrow "barreArbalete(Clone)" shot by the player or by a rock "Comête" throw by the player then activate the dead function.
    By i can't make the script detect for the collision by the Rigidbody of Collider[] colliders in the explosion script.
    I can't make the EnnemieAI script detect the Collider[] colliders of the Explosion script by the
    [OnCollisionEnter] or [OnTriggerEnter] function even if it push back all the object around.
    However it can detect the bomb gameobject but not his explosion

    I have made this work by making the explosion script called a dead function of alien when one of the rigidbody get hit by a collision but it make the code less good, less logical and i work only for an instance of alien in the scene.

    Thanks in advance for all of your response. :)
     
    Last edited: Nov 26, 2020
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    One approach is to do a Physics.OverlapSphere when the bomb goes off to get all colliders within the blast radius. Then you can iterate them and add impulsive forces to them.

    Personally I like to track all my own enemies that I care about and when I blow them up, I iterate that list and see who is close enough to get knocked around. Each enemy can have a trivial registration routine to add / remove itself from a list of known enemies, so the bookkeeping is pretty simple and out of sight.
     
  3. billydog132

    billydog132

    Joined:
    Nov 1, 2020
    Posts:
    16
    Hello Kurt-Dekker thanks for your response.
    that is exactly what i do in the Explosion script in the detonate() function.
    However the alien script can't detect the hit element of the Collider[] list and that is my problem.
    each alien should detect himself if he get hit by an explosion not an external script.
    Maybe it is bad practise but i am making a little school project so i doesn't matter for the moment.