- Home /
Set all non-static variable instances to a value?
helloo. so I have a script on multiple enemies each with their own health. I want to make a <button>
that, when pressed will set all enemy's health to 0
.
public class EnemiesWithHealth: MonoBehaviour
{
public float health;
void Update(){}
void Start(){}
public void KillAll() //for the button
{
health = 0;
}
}
I dragged in one of the enemy's gameobject into the button and assigned the KillAll()
function to it but when I press the button, it only sets the enemy I dragged into the button's health to zero, not all of them.
...
how to fix?
Answer by pako · Nov 18, 2017 at 06:25 PM
You must click on the plus '+' of the Button's OnClick() and add each of the Enemies' KillAll()
.
If there are too many enemies, you can subscribe to the button's OnClick() event through script:
https://docs.unity3d.com/ScriptReference/UI.Button-onClick.html
EDIT: I've added the code for doing it through script. First of all, create a new tag "KillButton", and assign it to the Button. This way, each enemy can Find the Button by searching for its tag. Here's the code:
using UnityEngine;
using UnityEngine.UI;
public class EnemiesWithHealth : MonoBehaviour {
public float health;
private Button killButton;
void Awake()
{
killButton = GameObject.FindGameObjectWithTag("KillButton").GetComponent<Button>();
}
private void OnEnable()
{
killButton.onClick.AddListener(KillAll);
}
private void OnDisable()
{
killButton.onClick.RemoveListener(KillAll);
}
void Update()
{
}
void Start()
{
}
public void KillAll() //for the button
{
health = 0;
}
}
ah thank you very much! that is an interesting way to do things!
@cerdajake thank you for describing my answer as interesting. However, please note that my answer is the CORRECT way to do things.
@cerdajake2008 $$anonymous$$y answer was based on the assumption that the EnemiesWithHealth
script is attached on each and every enemy, since you say
I have a script on multiple enemies
Is that so? Is this script on attached on each and every enemy?
BTW I have tried both of the solutions in my Reply and they work (as long as my above assumption is correct). I am also curious what is the $$anonymous$$ill()
method that @Dragate includes in his Answer.
It's a user defined function, the one defined by the OP as $$anonymous$$illAll(). I renamed it cause it actually doesn't kill all but only the enemy that the script is attached to. And used the $$anonymous$$illAll() name for another function that calls the various $$anonymous$$ill() functions.
@Dragate the logic of your answer is flawed, to say the least. What you are saying is that the Button should reference only one Enemy!!! i.e. the one Enemy whose GameObject is dragged in the Button's Inspector (as described in the question). Then, this one Enemy, will get a reference to all other enemies whenever the button is clicked, in order to call a $$anonymous$$ill() method, to set health = 0
. This is not the proper way of doing things! First of all, this is a very bad example of Program$$anonymous$$g. Secondly, what if the "one" important Enemy assigned to the button gets killed and it's GameObject is destroyed? The button will do nothing!
i think you mean your answer was "better" there isn't a right or wrong here. I chose Dragate's solution because I've done things similiar before and yours I've never done because I didn't know .addlistener existed and didn't feel comfortable leaving my beginner level comfort zone, i rather wanted to work in what I know to muscle memory before learning new things. I said yours was interesting because it seemed more of an experienced way to do it and when I was ready I would use it in other situations when the time came. I understand others will use these forum's answers as they are learning too and you don't want them to learn the wrong way but your answer being more experienced doesn't mean it is "correct". another beginner may choose either solution depending on how they choose to learn. if you think that is the "wrong way to learn" or even "conceptually wrong", that's an opinion and unless you have some majority vote you can't decide. thanks for the knowledge but I dont think it's worth fighting over who gets the best answer. regardless I gave you both rep but one more than the other :O edit: my only typo was ass.listener
@cerdajake2008 I understand and respect your point of view, and want to respond by emphasizing and clarifying some points. First of all, I had no personal benefit from unaccepting Dragate's answer and accepting $$anonymous$$e, since as you may very well know, you don't get any karma points awarded for accepting your own answer. I have also spent hours to answer this question, by copying your code to a project, fixing it, testing it, etc, as well as responding to all these comments. I have also patiently responded to most of Dragate's arguments, until I realized that there's no reason for me to continue arguing. So, as I had no personal benefit from all these, it becomes self-evident that my actions were for the benefit of the community. Of course, you and everyone else is entitled to an opinion. However, having an opinion does not mean that the opinion is correct about a particular course of action. And since you mentioned having a "majority vote", well I consider that good OOP principles, and knowledge of Design Patterns, who are both generally well accepted, and whose value is greatly recognized, provides me with the "majority vote". I never said that Dragate's answer didn't work, but in this particular case, there's a right and a wrong way to do things, and I never "fought" for getting my answer getting recognized as the best, especially since I had no personal benefit to do so, and "fighting" needs a motive. Nevertheless, I must admit that I failed to make him understand why my answer was better than his. To me, it feels like I am saying that a screw-driver is the best tool for fixing a screw in place, and having arguments that "using a screw-driver for that, is just my opinion", since you can also do it with a flat knife. O$$anonymous$$, fine! I've used a flat knife many times, before getting a screw-driver, but that doesn't mean that the screw-driver is not the correct tool. Lastly, my interpretation of "Best" as used in "Best Answer" is that it's objectively, rather than subjectively "Best".
I replied coz I thought someone might've wanted me to. also I didn't know there weren't karma points, i've only asked 7 questions total since starting program$$anonymous$$g 2 months ago. I just thought there was a problem coz how y'all were talking. <3<3<3<3 thanks again! no worries!
Answer by Dragate · Nov 18, 2017 at 05:21 PM
You'll have to collect all the instances of the class and one by one call the function you want. You can use FindObjectsOfType() (which is expensive) or if you have tagged the enemy the script is on, FindGameObjectsWithTag(). So your button should call from a different script the method KillAll(), which in turn calls Kill() and implements a logic that looks like this:
public void KillAll(){
EnemiesWithHealth[] enemiesScript = FindObjectsOfType<EnemiesWithHealth>();
for(int i = 0;i <enemiesScript.Length;i++){
enemiesScript[i].Kill();
}
}
OR
public void KillAll(){
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
for(int i = 0;i <enemies.Length;i++){
enemies[i].GetComponent<EnemiesWithHealth>().Kill();
}
}
Your answer
Follow this Question
Related Questions
A code to reset a variable after x time if another button is not pressed. Help! 2 Answers
An object reference is required to access non-static member 0 Answers
ERROR - An object reference is required to access non-static member 3 Answers
Adding an extra variable to GUI buttons? 2 Answers
Info on GUI 1 Answer