0

I'm currently writing a script to control environmental lighting of the scene. I have a drop down list and three scripts for different environmental lighting, script1, script2 and script3. In my control script, I wrote:

public class ControlScript : MonoBehaviour {

    public Dropdown dropdown;
    public script1 s1;
    public script2 s2;
    public script3 s3;

    public void change() {
        int option = dropdown.value;
        disableAll();

        switch (option){
        case 0: 
            s1.enabled = true;
            break;

        case 1:
            s2.enabled = true;
            break;

        case 2:
            s3.enabled = true;
            break;
        }

    private void disableAll() {
        s1.enabled = false;
        s2.enabled = false;
        s3.enabled = false;
    }
}

Then I attached this script to camera, set the scripts accordingly and set the change() method listens to the onValueChanged() event.

The change() method reacts correctly with the dropdown list, however, the scripts s1/s2/s3 are not enabled properly and thus performs no function. I tried to attach the s1,s2,s3 to the camera additionally, but doesn't seem to work.

Is there a way to solve this problem?

-------------------------------Edit Update------------------------------- The scripts s1, s2, s3 are just sudo codes to illustrate what I intend to do in this project. script s1 is an environmental lighting script using spherical harmonics, script s2 uses monte carlo sampling and script s3 uses median cut algorithm. The three scripts works well on their own when they are attached to the camera, however when I tried to control them using another script, after they have been disabled, even when setting them to be enabled the scripts still not function properly.

2
  • Without the contents of script1/2/3, knowing why enabling and disabling the script doesn't do what is desired is virtually impossible. Also, you should follow convention and name all of your class names with a starting capital letter, e.g. Script1 and preferably name it something meaningful, like LightingSetup1 Commented May 11, 2017 at 13:22
  • @Draco18s Thank you for your advice, however here the script is just sudocode to illustrate what I want to do. I attached the scripts to the camera object and tried with gameObject.GetComponent, however the script is still not working Commented May 11, 2017 at 13:52

2 Answers 2

3

You need to make sure that:

  • The class and script names of the three scripts are Script1, Script2 and Script3, i.e.: public class Script1 : MonoBehaviour {} and Script1.cs (case sensitive, please use a capital first letter for class names).
  • That all three scripts are assigned as a component to a game object.
  • That you have properly assigned the reference to all three of them, via Inspector, in the Control Script, like this: enter image description here

And it should all work, your code in the Control Script is ok.

Edit: try to use this code in all the three scripts, and look what happens in the console when you switch from Option A to B (or C etc.) in the dropdown (code is just for Script1, edit it for 2 and 3 ofc).

using UnityEngine;

public class Script1 : MonoBehaviour {

    private void OnEnable() {
        Debug.Log("Script 1 Activated");
    }

    private void OnDisable() {
        Debug.Log("Script 1 Deactivated");
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you very much for your advice, however this is exactly what I did, and the disable works well. After I called disableAll(), then in the change() method, even I see in the editor that script0 is ticked, and Debug.log(script0.enabled) prints true, the script is still not functioning. However if I don't call disableAll(), it would function normally.
Can you post the code of s1, s2 and s3? What's script0 btw?
s1/s2/s3 are just short names for the real scripts, and the scripts all implement long algorithms for different sampling methods. I'm not sure if it is the dropdown list that makes them not working.
I'll edit my answer and add some code, use it to make a quick test.
Thank you very much for your help! I have tested your code and it works fine in this scenario. However I tested with my own code, the problem is that, even before selecting anything in the dropdown list, the scripts are enabled until other options are chosen. If I disable the scripts in the Start() or in the editor before playing, even enable the script later won't work at all. Do you have any suggestions for this problem?
|
-1

Note: * As pointed out by @Programmer, if you're trying to use the class as a component to for a GameObject then you can't create it's instance using new yourself. As then it won't be known to Unity and it's core methods like Start,Update, OnXX won't be called. You should use new only if your solve goal is to use the Script as a normal C# class which has nothing to do with Unity.

You can't provide script itself as the value for the variables. Variables shown in the Inspector window expect objects. In case of scripts it's easy as you can just call their constructor to instantiate the instances like below

/* don't use `new` if scripts are inherited from MonoBehavior or are intended
 * to be managed by Unity. Instead use someGameObject.AddComponent<script1>
 * This will have to be done where script instance is created. 
 * This instance can be accessed by using the method provided in the second
 * part of this answer.
 */
s1 = new script1();
s2 = new script2();
s3 = new script3();

However if you're trying to share .enabled field between classes then you will have to find a way to share these instances. One way is to attach them on an empty object, lets call it OptionManager and attach all the scripts to it. Now you will have to provide an instance of OptionManager to the ControlScript by exposing a public field of it. After that you can get s1, s2, s3 in it's components, see the example below

public class ControlScript : MonoBehaviour {
    public ScriptManager scriptManager;
    public Dropdown dropdown;

    private script1 s1;
    private script2 s2;
    private script3 s3;

    void Start() {
        s1 = scriptmanager.GetComponent<script1>();
        s2 = scriptmanager.GetComponent<script2>();
        s3 = scriptmanager.GetComponent<script3>();
    }
    //.... rest of the code

9 Comments

Thank you very much for your answer! I tried a similar way by attaching the scripts to the camera object in the editor, then call GetComponent to enable/disable the script, but although it is shown as active, the script is still not functioning.
You're wrong: in the Inspector you can give a reference to ANY type (GameObject, Transform, a class inheriting from MonoBehaviour, etc.). Moreover, you can't create new instances of a MonoBehaviour subclass with the new keyword.
s1 = new script1(); should be s1 = gameObject.AddComponent<script1>();. See here for more information.
@Galandil No it wont work. A Script is not an instance in itself (it's a class, text if you will). We need to either create an instance ourselves or attach the script as a component to another object, then only we can assign it to a field in an objects component. Script itself can not be dragged on to the field in the inspector.
Script1 is not a simple class. It is a class with MonoBehavior because OPS used the enabled variable which can only be found on MonoBehavior. The main reason of inheriting MonoBehaviour is so that you can attach your script to your GameObject and I am sure that's what OP is doing. If you use the new keyword, you won't be able to do this. The Awake,Start and Update functions won't be called. You can't enable/disable the script. Already, two people have tried to correct you but failed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.