Search Unity

Slider / finding GameObjects for instantiated prefabs, can't drag & drop in editor

Discussion in 'Scripting' started by jrauden, May 7, 2017.

  1. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    I have searched everywhere for the answer to this and can't find it (in c#), but i know this is super simple:

    I have a UI slider that i am using as a health bar, i took alot of the code from the Unity Survival Shooter tutorial. My problem is this: In the tutorial the scene starts with a player already in the hierarchy, so all they had to do to apply the slider to their player.health was drag and drop in the editor.
    In my game the player is instantiated by a GameManager after initialization so i can't just drag and drop the slider using the editor.

    In my script i have a declaration of: public Slider healthSlider;
    Trying to get to that Slider through my script is proving to be way harder than i know it should be.
    I tried using: healthSlider = GameObject.FindGameObjectWithTag ("healthslider"); this won't work because i can't convert GameObject to Slider.
    So I tried:
    healthSlider = (Slider) GameObject.FindGameObjectWithTag ("healthslider");
    (trying to find the slider as a GameObject and typecast it to a slider, same problem basically.

    Now I just can't think of what else to try. All I'm trying to do is get a reference to that Slider. Currently it is a child of a UI>Canvas, does that matter?

    Thank you in advance for your help, i know this is an easy one. :)

    UPDATE:
    Okay, I'm an idiot. Slider is a component of the Canvas. So, now i have this:
    healthSlider = GameObject.FindGameObjectWithTag ("mycanvas").GetComponent<Slider> ();
    This gets compiled but i get the NullRefererenceException (object reference not set to an instance of an object). I don't understand why I'm getting this. Code is all below:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;

    public class Player2Controller : MonoBehaviour {

    private float speed = 4F;
    private float gravity = 20.0F;
    public float restartLevelDelay = 1f;
    private Vector3 moveDirection = Vector3.zero;
    private int Health;

    public Slider healthSlider;
    private GameObject myCanvas;


    void Awake()
    {
    //myCanvas = GameObject.FindGameObjectWithTag ("mycanvas");
    //healthSlider = myCanvas.GetComponent<Slider> ();
    healthSlider = GameObject.FindGameObjectWithTag ("mycanvas").GetComponent<Slider> ();

    }

    void Start()
    {
    Health = GameMgr.instance.playerHealth;
    }

    void Update() {
    CharacterController controller = GetComponent<CharacterController>();
    moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

    // RESTRICT DIAGONAL MOVEMENT (CONTROLS FEEL FUNKY WHEN THIS IS ON
    //if (moveDirection.x > 0)
    // moveDirection.z = 0;

    moveDirection = transform.TransformDirection(moveDirection);
    moveDirection *= speed;

    moveDirection.y -= gravity * Time.deltaTime;
    moveDirection.y = 0;
    controller.Move(moveDirection * Time.deltaTime);

    healthSlider.value = Health;
    }
     
    Last edited: May 7, 2017
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Yes you can, GameObject.FindGameObjectWithTag ("healthslider").GetComponent<Slider>();
     
  3. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Yes, i figured that one out just a few min ago, thank you for responding though. But now that nullrefexception is coming up. I dont get why though.
     
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
  5. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Last edited: May 7, 2017
  6. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Ok, I figured it out finally. I had to use FindObjectOfType to get a reference to my Slider. FindGameObjectWithTag could find it but i couldn't store it in my variable using that function. So I did this and it finally worked:

    Code (CSharp):
    1. if (GameObject.FindGameObjectWithTag ("healthslider")) {
    2.             healthSlider = (Slider) FindObjectOfType(typeof (Slider));
    3.         }
    thank you for the help gorbit99
     
    SoldierofYHVH likes this.
  7. mohitsabhi

    mohitsabhi

    Joined:
    Feb 11, 2017
    Posts:
    5
    Hi!! @jrauden & @gorbit99 I am having the same problem, can you please help, in my case I have a Slider under the PlayerUI Prefab, which is instantiated from the Player setup script and then the player speed should be controlled by a Slider called THROTTLE which is under the Player UI Prefab.

    The PlayerUI is getting instantiated from the Player setup script, but the Gameobject.find for Throttle slider returns a NULL reference exception.

    Attaching the Script; Player Setup and Player controller on a single file and also screen shot of the scene with PlayerUI prefab Hierarchy on the left side and Actual Player inspector on the right.

    Please tell me what's wrong and how to give the correct reference.

    Many thanks in advance.
     

    Attached Files:

  8. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Hello mohitsabhi,
    To find my slider I used: healthSlider = (Slider) FindObjectOfType(typeof (Slider));
     
  9. MuffinMyst

    MuffinMyst

    Joined:
    Nov 17, 2014
    Posts:
    13
    While that is one way to do what he wants, keep in mind, this will only be effective if you have only one slider.

    I happened to have two, Health and Energy. It always grabs the first one it finds, which is in my Case health. So when I need it to grab the Energy Slider...

    gorbit99 Is correct. Worked perfectly for me! Thank you for asking this question, and thank you all for the answers!
     
  10. bebitunay

    bebitunay

    Joined:
    May 31, 2019
    Posts:
    1
    for meny numbers of sliders I use "FindObjectsOfType" which return array of sliders

    life = (Slider)GameObject.FindObjectsOfType (typeof(Slider)) [0];
    fire = (Slider)GameObject.FindObjectsOfType (typeof(Slider)) [1];
     
  11. Anindo

    Anindo

    Joined:
    Jan 19, 2020
    Posts:
    1
    I am stuck, for me, the slider does show up in the public field when i hit play but throws NullException and can not carry out any line that references Slider. I am at a loss, I can not find anything anywhere, how am I supposed to use prefabs when I am not even using prefabs?
    Update: An alternative is to just call it from within, like,
    Code (CSharp):
    1. GetComponent<Slider>().maxValue = maxhealth;
    but my goal was to use it in reference mode, as in, I would call the "slider" every time i wanted to use its stuff after declaring it:
    Code (CSharp):
    1. public Slider slider;
    but could not get any working method...
     
    Last edited: Dec 17, 2021