First of all, I’m trying to set up a simple system on my level select scene so if Player Prefs (which is what is being used to determine which level you’re hovering over.) is equal to a certain number, a certain string will be displayed in the U.I text above.
I have this script attached to my text element in the U.I.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LevelNameSystem : MonoBehaviour {
private Text theText;
private int levelNumber;
// Use this for initialization
void Start () {
levelNumber = PlayerPrefs.GetInt("PlayerLevelSelectPosition");
}
// Update is called once per frame
void Update () {
if (levelNumber == 0)
{
theText.text = "Dread Plains";
}
if (levelNumber == 1)
{
theText.text = "Haunted Corridor";
}
}
}
And basically whenever I try to playtest that scene, I get a
on line 26 (the end of the code.)
Perhaps it’s simply due to my sleep deprivation but have I done something wrong that I can’t see here?
How are you assiging the value for theText?
You have a private variable Text theText. Since it’s not public or serialized, it means you aren’t dragging and dropping into it, so it’s not pointing to anything.
This script is attached to a GameObject that is not The Text UI element your wanting to change:
In that case, change the text from private to public and drag the Text from the scene into the editor location in the script.
This script is attached to the TextUI ( or a parent of that UI).
Then add this code:
// if the script is on the Text
theText = GetComponent<Text>();
// if the script is on the parent of the Text
theText = GetComponentInChildren<Text>();
Oh my gosh, thank you for that, now that I’ve actually had some sleep, this solution is rather obvious so thank you so much for pointing it out to me. Lol.
Okay, so I’ve now got a new problem in which the text does indeed change to “Haunted Corridor” if I’ve got level 2 (player.prefs == 1) however, switching between level 2 and level 1 causes the text to remain as “Haunted Corridor”.
Well, if you never update levelNumber, update doesn’t know. Honestly though, doing the display in your Update method isn’t the best way, but that’s another story.
The only time you are setting levelNumber is in start. So you either need to update levelNumber before you check it’s values (can do this in update if you want) or you skip using the variable and just check the value of the playerpref directly.
But again, there really isn’t a reason to do this in update. If you’re changing the value of the playerpref somewhere, you should be doing a call to a method to update your text value at that point instead of trying to change the text every frame.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LevelNameSystem : MonoBehaviour {
public Text theText;
private int levelNumber;
// Use this for initialization
void Start () {
levelNumber = PlayerPrefs.GetInt("PlayerLevelSelectPosition");
}
// Update is called once per frame
void Update () {
levelNumber = PlayerPrefs.GetInt ("PlayerLevelSelectPosition");
if (levelNumber == 0)
{
theText.text = "Dread Plains";
}
if (levelNumber == 1)
{
theText.text = "Haunted Corridor";
}
}
}
Ah! I have discovered the problem, my player position Player.Prefs is not updating upon moving the selector. So this code is technically working but at the same time, it isn’t because of another script not working.
Thanks so much for your help guys!
I’m beginning to suspect this is a XY problem. (http://xyproblem.info/) What is it that your actually trying to accomplish overall. Is this some list of buttons that should have the text of Levels that the player chooses from? If not what is this code your trying to work out suppose to be doing in the overall scheme of things.
Assuming you have a preset number of levels and you are just implementing a screen that the player chooses a level from I’d do it like this:
Create a UI Button in your scene (you could use Text if you want, but button seems like what you want if they are going to “choose” the level). Customize the button look, Text Component Font, Color, size all that jazz.
Add a Layout Element to this Button. Check its Min Width and Height and set them to the size you want the buttons to be.
Make it a Prefab and Call it something appropriate. LevelButton for example.
Delete that button from your Scene. Create a UI Panel. Add a Vertical Layout Group to it. Uncheck Force Child Expand Height (Leave Force Width Checked). Stretch out this Panel to be as wide as a button and tall enough to handle your buttons.
If you have more buttons than will fit that will require scrolling which we can handle later if necessary. Add this Panel to your scene and attach this script to it:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class LevelManager : MonoBehaviour {
// Drag your button Prefab in the editor
public Button buttonPrefab;
void Start()
{
InitializeLevelButtons();
}
void InitializeLevelButtons()
{
// Set this number statically (probably not the best)
// Or but some code in here using PlayerPrefs or whatever you have to
// Tell it how many levels you have;
int numberLevels = 4;
for (int i = 0;i<numberLevels;i++)
{
Button newButton = Instantiate(buttonPrefab, this.transform) as Button;
Text buttonText = GetComponentInChildren<Text>();
buttonText.text = GetStringFromLevelNumber(i);
newButton.onClick.AddListener(delegate { LoadLevel(i); });
}
}
void LoadLevel(int index)
{
// Code goes here to load your level
}
string GetStringFromLevelNumber(int index)
{
switch (index)
{
case 0:
return "Dread Plains";
case 1:
return "Haunted Corridor";
default:
return "ERROR!";
}
}
}
This will add a Panel to your Scene that dynamically creates as many buttons as you have levels, Sets their text, and click handler that if you click them will call a LoadLevel function
You only need to do this when the scene loads, no need to keep doing it over and over in Update.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class LevelNameSystem : MonoBehaviour {
public Text theText;
private int levelNumber;
// Use this for initialization
void Start () {
levelNumber = PlayerPrefs.GetInt("PlayerLevelSelectPosition");
}
// Update is called once per frame
void Update () {
Debug.Log (PlayerPrefs.GetInt ("PlayerLevelSelectPosition"));
levelNumber = PlayerPrefs.GetInt("PlayerLevelSelectPosition");
if (levelNumber == 0)
{
theText.text = "Dread Plains";
}
if (levelNumber == 1)
{
theText.text = "Haunted Corridor";
}
}
}
So you load up some scene that has some method for the player to select a “world” to go to. These images and positions should be setup when the scene loads. There is no reason for any of that code to be in Update. You basically setting the text on these objects over and over again (say 60 times a second). You should move all that out to a single Initialize function and set it there. The only code in update should be the code that checks if they choose a level and act on that.
Wait… which code shouldn’t be in Update? The Level Select or the Level Name?
I do apologize if I’m frustrating/annoying you in any form but I am still getting a handle on C# through video tutorials.
Everything you originally posted shouldn’t be in update. I assume these names are static. Level 0 Name Always == “Dread Plains” and Level 1 is always “Haunted Corridor”. So if they are static you only need to load up the text and set it one time. The level 0 Object needs its Text set to “Dread Plains” and the Level 1 Object needs its text set to “Haunted Corridor”. Once thats done one time… it will stay that while the entire time the player is on the level Select screen. There is no need to constantly reset the name. Which your current code does (about 60x a second).