Unity: Null While Making New Class Instance

Unity: Null while making new class instance


public class Rule : MonoBehaviour{}
Rule rule2 = new Rule();

You can't use new keyword to create new instance if you are inheriting from MonoBehaviour.

You should get exception that says:

You are trying to create a MonoBehaviour using the 'new' keyword.
This is not allowed. MonoBehaviours can only be added using
AddComponent(). Alternatively, your script can inherit from
ScriptableObject or no base class at all

Your code would have worked if you had public class Rule {} but you have public class Rule : MonoBehaviour {}.

Creating new instance of class that derives from MonoBehaviour:

Example class:

public class Rule : MonoBehaviour
{
public Rule(int i)
{

}
}

If you inherit from MonoBehaviour, you should either use GameObject.AddComponent or Instantiate to create new instance of it.

Rule rule2 = null;
void Start()
{
rule2 = gameObject.AddComponent<Rule>();
}

OR

public Rule rulePrefab;
Rule rule2;
void Start()
{
rule2 = Instantiate(rulePrefab) as Rule;
}

If the Rule script already exist and is attached to the GameObject, you don't need to create/add/instantiate new instance of that script. Just use GetComponent function to get the script instance from the GameObject it is attached to.

Rule rule2;
void Start()
{
rule2 = GameObject.Find("NameObjectScriptIsAttachedTo").GetComponent<Rule>();
}

You will notice that you cannot use the parameter in the constructor when you derive your script from MonoBehaviour.



Creating new instance of class that does NOT derives from MonoBehaviour:

Example class: (Note that it does not derive from "MonoBehaviour"

public class Rule
{
public Rule(int i)
{

}
}

If you don't inherit from MonoBehaviour, you should use the new keyword to create new instance of it. Now, you can use the parameter in the constructor if you want.

Rule rule2 = null;

void Start()
{
rule2 = new Rule(3);
}

EDIT:


In the latest version of Unity, creating new instance of a script that inherits from MonoBehaviour with the new keyword may not give you error and may not be null too but all the callback functions will not execute. These includes the Awake, Start, Update functions and others. So, you still have to do it properly as mentioned at the top of this answer.

Unity - Null Reference when instantiating new object

I'm not really sure why this happen. But you can fix this by change

temp = Instantiate(board[j,i]) as GameObject;

to

temp = Instantiate(board[j,i].gameObject) as GameObject;

Instantiated class with new keyword is null after Start method has ended and button is pressed. Unity3d

Looks like Awake was the method i was looking for.

Awake is called before Start, so doing the saveController instantiation in Awake allows for the instantiation to happen before MusicOn is called.

void Awake() 
{
saveController = new SaveController();
}

source: https://unity3d.com/learn/tutorials/topics/scripting/awake-and-start

Unity Static Instance becomes Null Reference on live code update

I suspect this is a limitation of live editing.

Consider: you've edited a class. In order for that updated file to be used, the code has to be recompiled and "injected" into the running game in place of the original version. Whilst any instances of your component can be serialized and deserialized to give some level of continuity post-edit (i.e. fields that aren't renamed will retain their values), the static field won't be - and, further, it would make no sense for Start to be re-run in the middle of the game, which is where your Instance is set.

You could prove this to be the case by storing another static variable in your class (a simpler one - like an int) and seeing what happens to that when you live edit. I'd imagine it would reset to zero.

Unity C# : custom Object is null BUT I can access its properties

Because Unity.Object works in a very peculiar way, basically it contains data regarding the managed object while pointing to the native object (crudely speaking).

Let's make an example: you create a new object inheriting from MonoBehaviour. Now you have two objects, one on the native side and one on the managed side. You can access the instanceID propriety of the managed object thanks to the fact that MonoBehaviour inherits from Unity.Object. Basically, the latter is used to show all the relative data of the object in the Inspector.

Now, you want to Destroy this game object by calling the same named method. The native object is actually destroyed, but the managed object is not, since all managed objects can only be destroyed by the garbage collector. It's at this point that Unity.Object becomes null: it's a trick of the Unity engine uses in order to avoid that you try to access a native object which doesn't exist anymore. Eventually, when the GC is called, this Unity.Object will be destroyed too.

And this is why you should never create an Unity object which inherits directly from Unity.Object, but only from MonoBehaviour or ScriptableObject.

How to use class instance in if condition that ignore != null

Readability should always be a higher priority so doing checks like if(c != null) or if(c == null) aren't a bad thing(They are a good thing), it shows that you meant to enter that function specifically for those circumstance were if(!c) can sometimes be misinterpreted because someone misses ! but to answer your question you can change your Class C to this:

class C
{
public static implicit operator bool(C obj)
{
return obj != null;
}
}

Be aware though, that just because you can if(collider) an object does not necessarily mean that implicit conversion means it isn't null it can mean something else. In the example code I posted it does check if the object isn't null.

Nested class of an instance is null

I've reproduced your classes in a Console apps(.NetCore and .NetFramework), it work just fine,
Maybe Clean\Rebuild would do.

Handling a null object in a derived class c# unity

The "right" way would be one of:

  1. Create another base class, e.g. BaseWeatherWithParticleSystem and only inherit from that if you do in fact supply a particle system
  2. Create an interface, e.g. IWeatherParticleSystem and implement that for the classes that need a particle system.

I'd lean to the interface approach. It makes testing easier and more clearly advertises the capabilities of the class. Mind you, you could implement both approaches, e.g.:

public class BaseWeather { ... }
public class BaseWeatherWithParticleSystem : BaseWeather, IWeatherParticleSystem { ... }

As for applying the interface to the base class or the derived class, that depends on the level of support your IDE provides for easily discovering the implemented interfaces from a class reference.

Just beware of trying to handle too much through inheritance and base classes. It's easy to program yourself into a corner trying to make everything fit into an inheritance hierarchy. I find you're often better off implementing things directly and then refactoring common code after you've got the basics set up.

As @maccettura noted in their comment, the "right" way seeks to avoid violating the SOLID principles.



Related Topics



Leave a reply



Submit