0
\$\begingroup\$

The Idea: Pressing a button in the canvas will allow the player to select a race. A script is attached to an object which is accessed though the OnClick() function of the button.

The script is supposed to get which race is selected based on which button is pressed and fetch a race description in a Text Object named "DescriptionText".

However a description is not displayed, and I get this error: "NullReferenceException: Object reference not set to an instance of an object GOnClick.GetRaceDesc () (at Assets/Scripts/GUI_Scripts/GOnClick.cs:24)".

I can't see what I am doing wrong, so here is my code:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class GOnClick : MonoBehaviour {

public string race, description;
void Start()
{
    race = "";
    description = "";
}

void Update()
{
    GetRaceDesc();
}


public void GetRaceDesc()
{
    //Button butnText = GameObject.FindObjectOfType<Button>();
    //race = butnText.GetComponentInChildren<Text>().text;
    *(line 24)* race = gameObject.GetComponentInChildren<Text>().text;
    GameObject descRect = GameObject.Find("DescriptionText");


    if(race == "Dark Elf")
    {
        BaseRace raceSelection = new DarkElfRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "High Elf")
    {
        BaseRace raceSelection = new HighElfRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Wood Elf")
    {
        BaseRace raceSelection = new WoodElfRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Human")
    {
        BaseRace raceSelection = new HumanRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Dwarf")
    {
        BaseRace raceSelection = new DwarfRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Orc")
    {
        BaseRace raceSelection = new OrcRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Goblin")
    {
        BaseRace raceSelection = new GoblinRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Tiefling")
    {
        BaseRace raceSelection = new TieflingRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Half Dragon")
    {
        BaseRace raceSelection = new HalfDragonRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }
    else if (race == "Werewolf")
    {
        BaseRace raceSelection = new WerewolfRace();
        descRect.GetComponent<Text>().text = raceSelection.CharacterRaceDesc;
    }

    }

}

Thanks in advance for any help.

\$\endgroup\$
8
  • \$\begingroup\$ It's not very clear what is the issue you're facing, could you edit your question? \$\endgroup\$
    – Vaillancourt
    Jul 6 '15 at 20:25
  • \$\begingroup\$ @AlexandreVaillancourt First of, thank you for being polite. Highly appreciated brother! Is my question more clear now? \$\endgroup\$
    – Valamorde
    Jul 6 '15 at 20:38
  • \$\begingroup\$ It is! Presumably, your gameObject.GetComponentInChildren<Text>() is probably null. Are you certain that the gameObject component hierarchy has a Text component? \$\endgroup\$
    – Vaillancourt
    Jul 6 '15 at 20:54
  • \$\begingroup\$ @AlexandreVaillacourt Turns out it is not accessing a button's text because it's trying to find a Text component of the object it's attached to which is an empty object with no child components. How would I access the button through the script? \$\endgroup\$
    – Valamorde
    Jul 7 '15 at 3:32
  • \$\begingroup\$ Sorry, I don't know about Unity enough to help you further. \$\endgroup\$
    – Vaillancourt
    Jul 7 '15 at 13:23
0
\$\begingroup\$

I made something to show you how I would do it, you can play around with it. I will explain how to use it.

Put the following script on any GameObject you like.

In the inspector, drag the text field where your race description should appear in the textField slot of this script.

As you can see I made up some classes for your races, I gave it an id and the description. The id is important, because now you will go to the button which should show the description.

Add a click listener to the button by pressing the "+" sign in the lower right of the button script.

Drag the GameObject which has the RaceSelection script to the open slot in the inspector.

You can now select a function to execute. Choose RaceSelection, then choose SetRaceDescription.

Another slot will appear where you can enter an integer. This integer corresponds to your race id. So by entering a 0 this button will show the High-Elf.

You have to do that will all your buttons, in each enter a different integer that corresponds to a race.

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

public class RaceSelection : MonoBehaviour {

    public interface Race
    {
        int RaceID {
            get;
        }
        string RaceDescription {
            get;
        }
    }

    public class HighElfRace : Race
    {
        public int RaceID {
            get {
                return 0;
            }
        }

        public string RaceDescription {
            get {
                return "High-Elf";
            }
        }
    }

    public class DarkElfRace : Race
    {
        public int RaceID {
            get {
                return 1;
            }
        }

        public string RaceDescription {
            get {
                return "Dark-Elf";
            }
        }
    }

    public Text textField;
    private IDictionary<int, Race> raceDict = new Dictionary<int, Race>();

    void Start() {
        addRaceToDictionary (new HighElfRace ());
        addRaceToDictionary (new DarkElfRace ());
    }

    private void addRaceToDictionary(Race race) {
        raceDict.Add (race.RaceID, race);
    }

    public void SetRaceDescription(int raceId) {
        textField.text = string.Format("Race : {0}", raceDict[raceId].RaceDescription);
    }

}

Some more guidance : You are calling GetRaceDesc in your Update method. This in itself isn't bad, but you are creating unnecessary objects in it and you are constantly looking up components. This will slow down everything. Either cache components in Start() or do it like I did in my script and drag and drop them in via inspector.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you, I figured it out on my own eventually after a lot of practice, but thank you for answering my question and being so clear on what should be done !! :D \$\endgroup\$
    – Valamorde
    Feb 17 '16 at 9:11
0
\$\begingroup\$

So your new question is How you would access the button through the script? I'd create the gameobject string and have it public so you can relate to a specific object in your scene. Then do an "OnGUI" you would name the var that you set up when you create the gameobject string. Hope that helped! :D

\$\endgroup\$
1
  • \$\begingroup\$ Could you add an example in code tag? it would be easier for me to read and understand. \$\endgroup\$
    – Valamorde
    Jul 7 '15 at 21:05
0
\$\begingroup\$

You can make public members in GOnClick to easily access other GameObjects and if you need the Text component, call GetComponent in your Start and save it so you only have to do it once.

public class GOnClick : MonoBehaviour {

    public GameObject RaceTextContainer;
    private Text RaceText;

    public string race, description;
    void Start()
    {
        RaceText = RaceTextContainer.GetComponent<Text>();
    }

    ...
}

Now, if you click on the object in your Hierarchy that has GOnClick attached and look at your Inspector you'll see an empty slot for "RaceTextContainer". You can now drag whatever object you want to extract the Text component from and drag it from the Hierarchy into that slot under the script in the Inspector.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .