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

@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 :slight_smile: