Cannot figure out error NullReferenceException: Object reference not set to an instance of an object
Following in the well worn footsteps of the first example (in C#) on this page, I created a script called Player.cs attached to an empty GameObject. I declare a List object called 'Gain' and in the Start function puts the value '3' into it ...
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Player : MonoBehaviour
{
public List<int> Gain = new List<int>();
// Use this for initialization
void Start ()
{
Gain.Add(3);
}
}
I created another script to access Player which contains this code ...
Player player = GetComponent<Player>();
if (player == null)
{
Debug.Log("Ouch");
}
else
{
Debug.Log(player.Gain[0]);
}
It builds ok but I get "Ouch" instead of "3".
The 2nd snippet, what function is that being called from? Or when is it called? If it's in a Start function, then there's no guarantee that Player Start() will happen before the 2nd script's Start(). For a quick test, in Player.cs, rename Start() to Awake().
The 2nd snippet is in a function that is called from a button press's On Click (), which was a different adventure in itself.
I wondered about the execution ti$$anonymous$$gs so put breakpoints in for testing - it's not that.
Since Jessespike is most likely right I'll stick to advice. I found out that you'll need to access the player instance quite often, specially in your first games, so making it a static variable in the player class is a good idea :p
public static Player player = this;
"keyword 'this' is not valid in a static property, static method or static field initializer".
public static Player player = player;
felt worth a try and did compile but still null.
However, changing List to be static -
public List<int> Gain = new List<int>();
to
public static List<int> Gain = new List<int>();
worked!
Thank you Ganda and @Jassespike for sending me down the right path.
Answer by psykojello2 · Oct 20, 2015 at 07:12 AM
My strategy with Awake and start is generally to do initialize everything specific to an object in its Awake function; and anything that requires knowledge of another object in its Start function.
So in Player, set Gain.Add(3) in your Awake() function
and your other code, check for Gain[0] in either a Start() function (or a function that gets called after Start).
Also, check that your Player object is active - if not, the Start function would not have got called yet.
If you can attach a debugger, put breakpoints on both the lines and see which gets called first. (or use Debug.Log statements).
The issue here is that my Player class is never instantiated - I'm just getting my head around the object oriented model.
Great advice though!
So did you get it to work? I see on the other thread you mentioned you used a static list to get it to work - that doesn't seem necessary and the static member will cause you other problems down the line.
@Ganda suggested using a static instance of the Player object (assu$$anonymous$$g there will be only one player in the scene at a given time) This is great and is called a singleton. The simplest way to do this is :
public class Player : $$anonymous$$onoBehaviour
{
public static Player instance;
public List<int> Gain = new List<int>();
void Awake()
{
instance = this;
}
// Use this for initialization
void Start ()
{
Gain.Add(3);
}
}
And you can access the player object from any other class like this:
if (Player.instance == null)
{
Debug.Log("Ouch");
}
else
{
Debug.Log(Player.instance.Gain[0]);
}
Now just make sure that you've attached your Player script to a game object and put it in the scene. That should ensure that everything is instantiated.
Yes, your singleton works wonderfully, thanks for that.
This is my first game, I'm feeling my way through it.
Your answer
Follow this Question
Related Questions
CAR ENTER EXIT 0 Answers
Unity HUD Tracking and Target Selection 0 Answers
Jump Animation Script and colliders not working properly 1 Answer
How do I make a x move and y move parameter 0 Answers
Declaring Array, HELP. 1 Answer