Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Splash Damage - Broken List

Discussion in 'Scripting' started by kittik, Feb 1, 2016.

  1. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    I am trying to create a function on an Explosion (GameObject) that looks for any eligible targets (Enemies) to inflict damage on, if they are within range (Splash Damage). To do this I have created a List for all spawned Enemies to go be added to, to then check whether or not they are in the Collider.

    I am having problems using a List to try to make my OnTriggerStay function effect more than one GameObject. To do this, I have created a List of the Objects, which the trigger should then be able to look at, so it can effect one or more. Lines 19 and 20 are causing the error cannot convert GameObject[] to GameObject. I am not entirely sure why, as I didn't think I was doing anything wrong.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class DamageBoltHit : MonoBehaviour {
    6.  
    7.     public List<GameObject> ListOfObjects;
    8.     public int Damage;
    9.     bool NeverDone;
    10.  
    11.     void Start()
    12.     {
    13.         ListOfObjects = new List<GameObject>();
    14.         NeverDone = true;
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         ListOfObjects.Add(GameObject.FindGameObjectsWithTag("Enemy"));
    20.         ListOfObjects.Add(GameObject.FindGameObjectsWithTag("MedicEnemy"));
    21.     }
    22.  
    23.     void OnTriggerStay(Collider other)
    24.     {
    25.         if(NeverDone = true)
    26.         {
    27.             foreach(GameObject go in ListOfObjects)
    28.             {
    29.                 if(go.transform == other.transform)
    30.                 {
    31.                     other.gameObject.GetComponent<EnemyHealth>().RemoveHealth(Damage);
    32.                     Debug.Log("DamageBoltHit damages " + other.name);
    33.                     NeverDone = false;
    34.                 }
    35.             }
    36.         }
    37.     }
    38. }
    Does anyone have any suggestions on why lines 19 and 20 are causing errors, or have any tips on how they might do Splash Damage, if this isn't the best way?

    Thanks.
     
  2. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    ...not a fix of what you got but more of a change... I would never do something like this using update and trigger stay. I would use Physics.OverlapSphere on explosion (since your enemies must have rigidbodies and colliders because you are trying to use triggers anyway). This way it's a single call on explosion and not dragging your game down on a framely basis. Also, trigger stay has always made anything I've done just plain sluggish... best to check once and be done.
     
    kittik and NotTesla like this.
  3. NotTesla

    NotTesla

    Joined:
    Feb 1, 2015
    Posts:
    24
    I believe it is because, and someone else correct me if I'm wrong, GameObject.FindGameObjectsWithTag() returns an array, not a list, I'd recommend creating a temporary array like this for both Enemy and Medic Enemy.
    Code (csharp):
    1.  
    2. GameObject[]  tempArray = GameObject.FindGameObjectsWithTag("Tag");
    3. for (int i = 0; i < tempArray.Length; i++) {
    4. ListOfObjects.Add(tempArray[I]);
    5. }
    6.  
    While this will work, I do not believe that using GameObject.FindGameObjectsWithTag every frame in the update loop is a good idea, instead, I think use OnTriggerEnter and OnTriggerExit like this:

    Code (csharp):
    1.  
    2. OnTriggerEnter(Collider other) {
    3.     if (NeverDone && (other.tag == "Enemy" || other.tag == "Medic Enemy")) {
    4.         ListOfObjects.Add(other.gameObject);
    5.         for (int i = 0; i < ListOfObjects.Count; i++) {
    6.             ListOfObjects[I].GetComponent<EnemyHealth>().RemoveHealth(Damage);
    7.             NeverDone = false;
    8.         }
    9.     }
    10. }
    11.  
    12. OnTriggerExit(Collider other) {
    13.     if (other.tag == "Enemy" || other.tag == "Medic Enemy") {
    14.         ListOfObjects.Remove(other.gameObject);
    15.     }
    16. }
    17.  
    EDIT: after reading novashots post, I decided to search the doc for Physics.Overlapsphere, it seems to have exactly what you need:
    http://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html
    you'll have to adapt it a little to fit in your tag system I think, but it should work more efficiently than my method.
     
    Last edited: Feb 1, 2016
    kittik likes this.
  4. kittik

    kittik

    Joined:
    Mar 6, 2015
    Posts:
    565
    Thank you @novashot and @NotTesla, I will take your advice and use Physics.OverlapSphere.
     
    Last edited: Feb 2, 2016
  5. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    A moot point now, but a tip for another time:

    List has an AddRange function that adds an entire collection to the List.
     
    kittik likes this.