enable and disable scripts using .enabled without hardcoding
i was a little puzzled on what to name the question but let me try and explain..
I have a player with 3 scripts.. Lets call them ScriptOne, ScriptTwo, ScriptThree.
I have 3 ui buttons and depending on the button clicked, i was to disable the current script that is enabled, and enable the script assigned to that buttom. (Lets say for button 1 i want to have only ScriptOne enabled, and so on for the other two buttons
At the start of my game only ScriptOne is enabled on my gameObject. if i click Button 2 i would need to disable ScriptOne and Enable Script 2. The problem is that i wouldnt know whether the current enabled script was script 1 or three; so i would have to disable all of the scripts to make sure the right one is disabled.
ButtonTwo()
{
//this is the Button that was clicked, which called this method on the //game object
gameObject.GetComponent<ScriptOne>().enabled = false;
gameObject.GetComponent<ScriptThree>().enabled = false;
gameObject.GetComponent<ScriptTwo>().enabled = true;
}
This solves the problem by making sure all other scripts are disabled, then enables the script that is supposed to be enabled. The problem is what if there were 20 scripts instead of 3? that is a lot of "hardcoding" if i'm using that term right.
the way i tried to get around doing it was by trying this. (assume that ScriptOne is always enabled at the game start, then Button 2 is clicked to enable ScriptTwo and disable the other script)
public class Script: MonoBehaviour
{
Component lastScript;
void Start()
{
lastScript = gameObject.GetComponent<ScriptOne>();
}
ButtonTwo()
{
gameObject.GetComponent<lastScript>().enabled = false; //error
gameObject.GetComponent<ScriptTwo>().enabled = true;
lastScript = gameObject.GetComponent<ScriptTwo>();
}
}
The error here is that GetComponent takes a Type and not a Component, so that doesnt work. I've been trying for a long while now to figure out how to fix my problem but i haven't found a solution. Can anyone give me some help and point me in the right direction?
Thanks!
Answer by DiegoSLTS · May 22, 2016 at 11:23 PM
"The error here is that GetComponent takes a Type and not a Component"
That's because you keep using the generic version, and when you call a generic method you must have a specific type at compile time.
You can use the version that takes the type as a parameter and returns a Component instead, this should work:
gameObject.GetComponent(typeof(lastScript)).enabled = false;
EDIT: Also, I'd remove the "gameObject." part of those lines, it's redundant. And I'd use a method to enable/disable the scripts to clean the code a little:
public class Script: MonoBehaviour
{
Component lastScript;
void SetLastScript(Component newLastScript) {
lastScript.enabled = false;
lastScript = value;
lastScript.enabled = true;
}
void Start()
{
lastScript = GetComponent<ScriptOne>();
}
ButtonTwo()
{
SetLastScript(GetComponent<ScriptTwo>());
}
}
Thanks for the solution and tips! I was trying to use typeof at one point but now I see that I used to the wrong way. thanks!
Now that i actually got home and tried to implement this i found out that you cant use .enabled with a Component, so the first solution you showed me didnt work and niether did lines 6 and 8, could i have some help as to what im doing wrong?
You're right, sorry, Component doesn't have an "enabled" property, I thought it had.
For the first solution, since you know the components you're getting are $$anonymous$$onoBehaviours you can safely cast the returned Component to $$anonymous$$onoBehaviour and then set the enabled property:
$$anonymous$$onoBehaviour script = ($$anonymous$$onoBehaviour)gameObject.GetComponent(typeof(lastScript));
script.enabled = false;
For the second solution you should be able to change the type of lastScript the parameter of SetLastScript to $$anonymous$$onoBehaviour and polimorfism would do the rest:
public class Script: $$anonymous$$onoBehaviour
{
$$anonymous$$onoBehaviour lastScript;
void SetLastScript($$anonymous$$onoBehaviour newLastScript) {
lastScript.enabled = false;
lastScript = value;
lastScript.enabled = true;
}
void Start()
{
lastScript = GetComponent<ScriptOne>();
}
ButtonTwo()
{
SetLastScript(GetComponent<ScriptTwo>());
}
}
I never knew that you could use monohehaviour like that. For so long i've been trying to find something i can cast scripts as and as far as i got was using Component over the numerous time i've looked it up, but i never thought of it that way! I learned a whole new trick, thank you so much :D
Answer by Free_Radical · May 22, 2016 at 10:54 PM
Simple solution:
Have all scripts you're using inherit from an empty base type, which inherits from Mono so you can keep the functionality. Use gameObject.GetComponents of the type you've created, then you can go through and disable all scripts except for the one you want enabled using a foreach loop.
Answer by aLovedHater · May 22, 2016 at 11:12 PM
Is there a way to do it the way i was trying to?
It works pretty much precisely the way you wanted to, but with the added base wrapper. Another way is to have a master script controller attached to the object that stores all the scripts you want attached to the object to flip on/off into a collection, and then perform the same operation I just provided.
Your answer
Follow this Question
Related Questions
Edit variable of component by type 0 Answers
How do I give an object a script component of a type specified by the calling source? 1 Answer
How to correctly handle NullReferenceException when using GetComponent<>? 1 Answer
Game Manager can't decide what the instance of the object is despite just making an instance of it 1 Answer
Get Component isn't working too well 1 Answer