Receiving String from Variable in other Object

#Original Question:
Ok before you say, there are loads of topics about this.

I know… there are about 600 on just the NullRefference issue.

And i ofcourse dont wanna add questions that aren’t usefull to the question database.

The thing is. they honestly didn’t work for me. or i have looked exactly at 10 wrong versions?

i want to grow as a unity coder/designer. So i need to understand this.

I also want to turn this question into something quick and useful for others to read once i get this working. :slight_smile:

I understand that NULL bassicly means that theres no data to give.
So i need to define where it has to get the info. in my case i think its because my script is inside a object called “Player2”
thats what i think atleast… anyways here is how simple my code is.

They are two seperate scripts each in there own object. one is in a cube named “Player2” the other is in a mesh text object named “New Text”

using UnityEngine;
using System.Collections;

public class Player_Controller : MonoBehaviour {

	public float direction;
	public string Str_direction;
	//public string test_if_works = "working";
	
	void Update () {
		direction = Input.GetAxis("Horizontal");
		if (direction < 0.0)
			Str_direction = "left";
			//print("test"+printresult);
		if(direction > 0.0)
			Str_direction = "right";
			//print("test"+printresult);
		if(direction == 0.0)
			Str_direction = "stationary";
			//print("test"+printresult);	
	}
}

using UnityEngine;
using System.Collections;

public class FloatingTextSimple : MonoBehaviour {

	public GameObject Player2;
	private Player_Controller Player_Controller_taken;

	void Start () {
		Player_Controller_taken = Player2.GetComponent<Player_Controller>();

	}
	void Update () {

		//string newdir = transform.Find("player2").GetComponent<Player_Controller>().Str_direction();
		GetComponent<TextMesh>().text = Player_Controller_taken.Str_direction;
	}
}

Now the code might look a bit odd. But i tried hundreds of things. And i constantly get NULLRefference errors or different types of erros. But the way i have it now seems to give the least errors atleast…

What am i trying to achieve?
I am trying to display the debug text ingame on text mesh.

Why use text mesh?
Because i read somewhere that its easier and less code (only a few lines)

I think im not understanding the fundamentals. And i would like to ask ontop of this question if somebody can teach me a method where i can learn this easier myself. i one time found a youtube video who did this but i lost it. The unity script reference docs are very confusing to me. They dont explain the core or something for me. but i might be missing that core. And so many tutorials on youtube they go… ok this part of code just copy paste… and im like… Thats the tutorial?? Copy pasting code? how about understanding it…

The Error Message

(leads to my mesh text script)
NullReferenceException: Object reference not set to an instance of an object FloatingTextSimple.Update () (at Assets/Scripts/FloatingTextSimple.cs:16)

NullReference errors are one of the easiest to track down and solve.

Basically there’s 2 spots in your code where it’s even possible for one to occur. Line 33, and Line 39.

To determine which is the culprit, just print out Player2 as the first line in your Start method. If null, it means your Player2 variable isn’t correctly linked or set in Unity. Check the Inspector view for the object. The other one could be due to Player2 not having a “Plyaer_Controller” script on it, or due to the gameobject that “FloatingTextSimple” is attached to doesn’t have a “TextMesh” on it.

Now how to improve your code… Here’s some issues and coding practices that should help you if you stick to them.

  • Never use GetComponent and trust blindly that it will return a value. Always store the result, check if it’s not null, and act accordingly.
  • Use coding standards for naming your variables.
  • Don’t use underscores in class names.
  • Start variables lowercase and camel case them
  • Don’t use underscores in variables unless they’re all caps and therefore are constants.
  • If you find yourself using GetComponent in an Update loop, don’t. Get it once in Start or something and store it in a variable, which you then use in your Update loop or wherever.
  • Don’t use .Find() as it is slow
  • Don’t use strings for multiple option cases. That’s what enums are for. Make an enum of each case and switch on it when you need to test.

Hope I came across as helpful and not discouraging, as that is my intention. Criticism will be the only way you improve, so I hope this helps you become a better programmer!

First off, I think I see your problem, but I’m going to walk you through how I’d find it.

So your error says that there’s a problem at FloatingTextSimple.cs line 16,

GetComponent().text = Player_Controller_taken.Str_direction;

The error says you’re referencing something that doesn’t exist. So look at the objects you use on that line. There’s a few different objects.

First, Player_Controller_taken You’ll have to see if that’s actually set to something on start:

void Start () {
       Player_Controller_taken = Player2.GetComponent<Player_Controller>();

        if(Player_Controller_taken == null) {
              if(Player2 == null){
                    Debug.LogError("assign a player 2 object in the editor");
              }
              else{
                    Debug.LogError("No Player controller on Player 2");
              }
        }
 
    }

If that shows an error in the debug log, then you would need to make sure that Player2 is assigned in the editor, and that the player2 object has a Player_Controller Script.

So. You’ve verified that there is a player controller on Player 2 and it doesn’t throw an error on start.

Now, we go back to Line 16 and see that if the Player_Controller_taken is not the problem, something else is.

So you see you’re accessing Player_Controller_taken.Str_direction; Maybe that’s the problem. So now we go look at the Player Controller script. It looks like, as long as Update() has ran once, Str_direction has been set…but what happens if the text script tries to access Str_direction, before it’s been set to something? Who knows, so let’s go ahead and set it on start, just to make sure it exists

Player_Controller.cs:

void Start(){
    Str_direction="";
}

Now. If there’s still an error when we run it, then we’d go back to line 16 (assuming thats where the error still is). At this point, we know that the right side of the equals works, so maybe the error is on the left side.

GetComponent() should return the textMesh component, but perhaps that’s null. We can check first:

if(GetComponent<TextMesh>()== null) Debug.LogError("no text mesh attached");

So now, if we hit that in the Debug.Log, we know that this object doesn’t have a text mesh on it and that’s the problem.

Your scripts are working fine. Your Player2 game object reference is the culprit. You are getting the null reference exception because you are using Player2, which is null, to get your Player_Controller component.

Player_Controller_taken = Player2.GetComponent<Player_Controller>();

Since you’ve made Player2 public, it becomes visible within the Unity inspector. Just make sure you’re connecting that game object reference in the Unity inspector by dragging and dropping your cube object (which contains your Player_Controller script) from the hierarchy, onto the Player 2 property in the FloatingTextSimple script which is attached to your New Text object.

Do that and you’re golden.