Search Unity

how-can-i-access-a-gameobject-in-one-class-from-another-class

Discussion in 'Getting Started' started by lspence812, Jan 21, 2017.

  1. lspence812

    lspence812

    Joined:
    Feb 18, 2015
    Posts:
    5
    I have a slider in my OptionsController and Options screen. I need to access it from my GameStartController, so that when my game starts I can have the slider on my Options screen reflect the value I've set in the code of my GameStartController. How can I accomplish that?

    In my OptionsController I have:

    Code (CSharp):
    1. public Slider volumeSlider;
    In my GameStartController I have the following, but get a nullreference exception when my game starts. I'm a noob with unity.

    Code (CSharp):
    1. private OptionsController volSlider;
    2.  
    3. void Awake()
    4. {
    5.     volSlider = GameObject.FindObjectOfType<OptionsController>();
    6. }
    7.  
    8. void Start()
    9. {
    10.     volSlider.volumeSlider.value = 0.8f;
    11. }
    I'm using Unity 5.4.2f2, please help.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    When you say something like "I get a NullReferenceException" always copy and paste the actual error from your Console. It includes useful details, like exactly where the error occurred.

    But in this case I guess it must be on line 10 of GameStartController.cs. So that means either volSlider is null, or volSlider.volumeSlider is null. You can check for both of these:

    1. First, make sure you have actually dragged the relevant slider into the volumeSlider property of your OptionsController in the inspector. You didn't mention doing that, so I bet this is the problem.

    2. Then, try to never write code that assumes everything is set up correctly. Instead write worried, paranoid code that is just sure every other component in the project (including the one between the seat and the keyboard) is a complete moron that's going to fail to do what it's supposed to do. In this case, insert these lines into GameStartController.Awake, between lines 5 and 6:

    Code (CSharp):
    1. Debug.Assert(volSlider != null);
    2. Debug.Assert(volSlider.volumeSlider != null);
    These lines "assert" the things you were assuming before, which means it checks them and (in debug builds) raises an error if they are not true. So if something else has in fact failed to be hooked up properly, you will find out right away, and you'll know which one is the problem by which line is raising the error.
     
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,521
    Just put a script on your Slider GameObject.

    Code (csharp):
    1. public Slider controlThis; // drag the Slider component into this field in the inspector.
    2. public static float volume;
    3.  
    4. void Awake()
    5. {
    6.     if (controlThis == null) controlThis = GetComponent<Slider>();
    7. }
    8.  
    9. void Update()
    10. {
    11.     if (controlThis != null) volume = controlThis.value;
    12. }
     
  4. lspence812

    lspence812

    Joined:
    Feb 18, 2015
    Posts:
    5
    Thanks for the replies. I want to make sure you understand what I have and what I'm trying to do. On my Options scene I have a slider that controls the music volume. On my GameStartController I have buttons like "Start", "Options" and "Quit". I have a OptionsController tied to my Options screen and a GameStartController tied to my GameStart scene. When you start the game the GameStartController and GameStart scene are what is run first. I'm trying to set the music volume level in my GameStartController and also have the set volume level set in the volume slider that is located in my Options scene. This way when you start the game and the music volume level is set to say 0.5 and you go to the Options screen the slider will be set in the middle.
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Because they're different scenes, the slider can't access GameStartController and vice versa.

    There are various ways to get the data from one scene to the next, but I presume you also want to save this volume between runs of the game. So you'll need to use PlayerPrefs.

    Your GameStartController script should just read the volume level from PlayerPrefs (probably with PlayerPrefs.GetFloat).

    In the Options scene, your OptionsController script should also read the volume level upon start, and store the volume level (with PlayerPrefs.SetFloat) whenever the slider is moved. (The slider provides an event for when its value changes; you'll just hook that up to a public method on the OptionsController script.)
     
  6. lspence812

    lspence812

    Joined:
    Feb 18, 2015
    Posts:
    5
    Thanks, I'm already making use of PlayerPrefs. I worked it out, I think by discussing it out, I figured out what I needed to to. What I did to resolve it was in Start() within my GameStartController I first checked whether the music volume had been set in PlayerPrefs and if not set it to a certain level and saved that in PlayerPrefs, otherwise I set the music level to the value already stored in PlayerPrefs. The first time running the game it obviously won't be set. I did the same thing in Start() within my OptionsController, but instead of setting the music volume I set the volume slider.

    Thanks for helping me to take a step back and think about what I needed to do.
     
  7. smacbride

    smacbride

    Joined:
    Jan 10, 2015
    Posts:
    50
    Check out the adventure game tutorial, it goes over multiple scenes and using saved prams between scenes etc.