- Home /
Initializing Prefab returns NullPointerException
Hello,
I am recreating the portal mechanic from - who guessed it - Portal.
I try to instantiate a prefab which I assigned in the inspector. The command returns an Exception "ArgumentException: The Object you want to instantiate is null."
The portal prefab itself is just an empty go with a (child) plane and an attached material in the mesh renderer component from the plane.
See code and screenshot as reference.
A latest thought was that my problem might be the inner class, but I dont why it should not work. If somebody would please explain me what I am doing wrong, I dont find the solution.
My Code:
public class PortalController : MonoBehaviour {
[System.Serializable]
public class Portal
{
[Header("Settings / Prefabs")]
public Camera portalCameraPrefab;
public GameObject portalPrefab;
public Material portalMaterial;
[Header("Runtime Variables")]
public Vector3 coordinate;
public Vector3 surfaceNormal;
public GameObject portalGO;
public Camera ownCam; // camera sits with own portal // renders texture for other portal
public Portal(Vector3 _coordinate, Vector3 _surfaceNormal)
{
coordinate = _coordinate;
surfaceNormal = _surfaceNormal;
portalGO = Instantiate(portalPrefab, _coordinate, Quaternion.Euler(_surfaceNormal)); //´this call fails´
portalGO.SetActive(false);
ownCam = Instantiate(portalCameraPrefab, _coordinate, Quaternion.Euler(_surfaceNormal));
ownCam.gameObject.SetActive(false);
}
public void ActivatePortal(Vector3 _coordinate, Vector3 _surfaceNormal)
{
portalGO.transform.position = _coordinate;
portalGO.transform.rotation = Quaternion.Euler(_surfaceNormal);
portalGO.SetActive(true);
ownCam.transform.position = _coordinate;
ownCam.transform.rotation = Quaternion.Euler(_surfaceNormal);
//ownCam.gameObject.SetActive(true); // Not active until second portal appears
}
public void DeactivatePortal()
{
portalGO.SetActive(false);
ownCam.gameObject.SetActive(false);
}
}
public Portal portalA;
public Portal portalB;
private bool portalAorB;
// Use this for initialization
void Start () {
portalAorB = true;
portalA = new Portal(Vector3.zero, Vector3.zero);
portalB = new Portal(Vector3.zero, Vector3.zero);
}
...
Screenshot:
Thank you in advance! Greetings Kevin
Answer by hrishihawk · Jan 30, 2018 at 05:21 PM
@Arcandos Hi Kevin ,I have looked into your code and found the problem. When you create an instance of the class all the variable in that instance is assigned their default value.I will explain what happens with your code with a simpler example.
public class Numbers : MonoBehaviour {
[Serializable]
public class AdditionCalc
{
public int num1,num2;
public AdditionCalc(int a,int b)
{
print(num1+num2);
/*When this line is executed you will always get the result as 0 becuase default value for num1 and num2 is 0 */
}
}
public AdditionCalc add1;
public AdditionCalc add2;
private void Start()
{
add1 = new AdditionCalc(1,2);
add2 = new AdditionCalc(3,4);
}
}
So you need to assign the variable their expected value in constructor as follows
public AdditionCalc(int a,int b)
{
num1 = a;
num2 = b;
print(num1+num2);
/*When this is executed you will get the expected results because you are assigning values to your variables*/
}
Now coming to your Portal problem.You create instances of the class Portal as PortalA and PortalB.And in the constructor you are trying to instantiate portalPrefab whose value is set to it's default value (Null) in the new instances PortalA and PortalB.Which is why you get the error. To overcome that you can change your constructor to something like this :
public Portal(Vector3 _coordinate, Vector3 _surfaceNormal,GameObject portal,Camera cameraPrefab)
{
print(a1+b1);
coordinate = _coordinate;
surfaceNormal = _surfaceNormal;
portalGO = Instantiate(portal, _coordinate, Quaternion.Euler(_surfaceNormal));
portalGO.SetActive(false);
ownCam = Instantiate(cameraPrefab, _coordinate, Quaternion.Euler(_surfaceNormal));
ownCam.gameObject.SetActive(false);
}
And then create instances of the Portal class with the required prefabs :
public Portal portalA;
public Portal portalB;
public GameObject portalAPrefab,portalBPrefab;
public Camera cameraA, cameraB;
private bool portalAorB;
// Use this for initialization
void Start()
{
portalAorB = true;
portalA = new Portal(Vector3.zero, Vector3.zero,portalAPrefab,cameraA);
portalB = new Portal(Vector3.zero, Vector3.zero,portalBPrefab,cameraB);
}
Hope I was able to clear the doubts you had. Cheers :)
Thank you, you are absolutly correct. As you mentioned, I discard the instance which I create through the editor when I create and assign a new one at runtime.
$$anonymous$$y solution was, ins$$anonymous$$d of dragging the prefab variables out of the inner class, to replace the constructor with a method. Now I only call the InitializePortal() $$anonymous$$ethod for the editor-prepared-instance ins$$anonymous$$d of creating a new instance. I only want those 2 objects. I will be moving them around, ins$$anonymous$$d of destroying and recreating them. So I dont need a constructor.
public void InitializePortal(Vector3 _coordinate, Vector3 _surfaceNormal)
{
coordinate = _coordinate;
surfaceNormal = _surfaceNormal;
portalGO = Instantiate(portalPrefab, _coordinate, Quaternion.Euler(_surfaceNormal));
portalGO.SetActive(false);
ownCam = Instantiate(portalCameraPrefab, _coordinate, Quaternion.Euler(_surfaceNormal));
ownCam.gameObject.SetActive(false);
}
Greetings $$anonymous$$evin
Your answer
Follow this Question
Related Questions
ArgumentException: The prefab you want to instantiate is null. 1 Answer
Some Prefabs are not Loading 1 Answer
the prefab you want to instantiate is null 1 Answer
Instantiating prefab from another script. Error, prefab is null. 1 Answer
prefab is null when I try to instantiate from another script 1 Answer