Jump to content
  • Advertisement
Sign in to follow this  
4d69636861656c

Unity Object reference not set to an instance of an object

This topic is 883 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having this problem in Unity when trying to initialize a few variables. I have an example below.

 

public class PlanetDetails
    {
        private int planetID;
        private string planetName;

        public int PlanetID
        {
            get { return planetID; }
            set { planetID = value; }
        }

        public string PlanetName
        {
            get { return planetName; }
            set { planetName = value; }
        }
    }

 

PlanetDetails[] Planet = new PlanetDetails[10];
 

...

 

Planet.PlanetID = (System.SystemID + Random.Range(0, 1000));
Planet.PlanetName = "Test" + i;
Debug.Log(Planet.PlanetID);
Debug.Log(Planet.PlanetName);

 

When I try to initialize a variable, it gives me an error in Unity, and since I'm pretty new to programming,  I can't understand why. Any help would be great.

Share this post


Link to post
Share on other sites
Advertisement
Planet[i] = new PlanetDetails();
You can only skip that step if you're using an array of value types (int, bool, float, enum, struct - basically everything that's not a class).

When you make an array, its entries are all set to the "default" value of the corresponding type.

int: 0
float: 0.0f
double: 0.0
all the other numeric and enum types = whatever their concept of 0 is.
bool: false
class: null
struct: non-null, each individual field = its own default

In this case you have a class, so the default is null; You need to individually 'new' each element in the array. Edited by Nypyren

Share this post


Link to post
Share on other sites

What is the exact error message, and what line is it on?

 

NullReferenceException: Object reference not set to an instance of an object
GameGUISystemDetails.Start () (at Assets/Scripts/GameGUISystemDetails.cs:157)

 

The line is this: Planet.PlanetID = (System.SystemID + Random.Range(0, 1000));

If I comment this line, the warning will go to the next line, which is the initialization of Planet.PlanetName and so on.

Share this post


Link to post
Share on other sites

So the problem is that you are expecting the elements of the array to be there, but they're not.  You're only allocating the space for the elements in your array, you then need to put something there.  

PlanetDetails[] Planet = new PlanetDetails[10];
for(int i=0; i<10;i++)
  Planet[i]=new PlanetDetails();

Cheers, 

 

Bob

Share this post


Link to post
Share on other sites

So the problem is that you are expecting the elements of the array to be there, but they're not.  You're only allocating the space for the elements in your array, you then need to put something there.  

PlanetDetails[] Planet = new PlanetDetails[10];
for(int i=0; i<10;i++)
  Planet[i]=new PlanetDetails();

 

:D Thank you, I completely forgot about that ...

Share this post


Link to post
Share on other sites

The Linq based solution is below, I prefer as less "moving parts" to screw up :)

 

PlanetDetails[] Planet = Enumerable.Repeat(0, 10).Select(_ => new PlanetDetails()).ToArray();

 

I am using _ as the select variable passed in as it is not used

Share this post


Link to post
Share on other sites

As a follow up, in the above Range and Repeat are interchangeable given we are not using the value in _

 

var Planet = Enumerable.Repeat(0, 10).Select(=> new PlanetDetails()).ToArray();

 

 

var Planet = Enumerable.Range(0, 10).Select(=> new PlanetDetails()).ToArray();

 

There is a more subtle use of repeat

 

Func<PlanetDetails> buildPlanet = () => new PlanetDetails();

var Planet = Enumerable.Repeat(buildPlanet, 10).Select(build => build()).ToArray()

 

This returns the same planet factory 10 times, we then call the builder in each case and slot the results into an array

 

:)

Share this post


Link to post
Share on other sites
Just curious: My C# is rusty, but isn't there anything like this?
 
private static IEnumerable<T> Generate(Func<T> f) {
    while (true) yield return f();
}

Used like so:
 
var Planets = Generate(() => new PlanetDetails()).Take(10).ToArray();

Feels a bit more straightforward than WozNZ's suggestions. Edited by kloffy

Share this post


Link to post
Share on other sites

Just curious: My C# is rusty, but isn't there anything like this?
 

private static IEnumerable<T> Generate(Func<T> f) {
    while (true) yield return f();
}
Used like so:
 
var Planets = Generate(() => new PlanetDetails()).Take(10).ToArray();
Feels a bit more straightforward than WozNZ's suggestions.

 

 

Nice one, very explicit. For some reason I forgot about using a generator

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!