1
\$\begingroup\$

I'm trying to create a bunch of different game objects from a settings file I'm passing in at run time. I've checked and my game is reading in settings fine. But when I run the program, I get the following error:

ArgumentException: The prefab you want to instantiate is null.

But, I still get two cameras appearing in my scene. So I'm confused as to why this is happening.

Here is the code that is acting on the information received from the settings file:

public void CreateCamera()
{


for (int i = 0; i < testCamera.Count; i++)
{

    camera = Instantiate(gameObject.AddComponent<Camera>(), new Vector3(0, 0, 0), Quaternion.identity) as Camera;
    camera.name = testCamera[i].Name;
    camera.near = Convert.ToSingle(testCamera[i].Near);
    camera.far = Convert.ToSingle(testCamera[i].Far);
    camera.aspect = Convert.ToSingle(testCamera[i].AspectRatio);
    camera.fov = Convert.ToSingle(testCamera[i].FOV);
}

}

Following this, I also get the following message as well:

Can't add component 'Camera' to GameObject because such a component is already added to the game object!

Can anyone help me in fixing these issues?

\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

What the error messages are saying is that 1) You can't add a camera to the existing game object because you can only have one camera component per game object (a limitation of Unity) 2) because of 1) the return value of your AddComponent is null and therefore 3) Instantiate is failing.

Your code doesn't really make any sense because you're trying to add multiple cameras to the same game object. camera.name changes the name of the game object the camera is attached to. Components themselves don't have names.

Basically, you don't want to use Instantiate. That's specifically for creating instances of prefabs. Just do new GameObject() and then add the camera to it. The rest of your code should be the same. E.g.:

for (int i = 0; i < testCamera.Count; i++)
{

    var cameraGameObject = new GameObject( testCamera[i].Name );
    var camera = cameraGameObject.AddComponent<Camera>();
    camera.near = Convert.ToSingle(testCamera[i].Near);
    camera.far = Convert.ToSingle(testCamera[i].Far);
    camera.aspect = Convert.ToSingle(testCamera[i].AspectRatio);
    camera.fov = Convert.ToSingle(testCamera[i].FOV);
}

(Also you might not want to use the variable name camera as it's a property on MonoBehaviours that essentially does GetComponent<Camera>. That might be messing you up as well.)

\$\endgroup\$
1
  • \$\begingroup\$ What @Tetrad did is a great debugging technique: when experiencing a confusing problem start from the beginning and verify each step, looking into the API documentation for each system/engine call, watch your debug outputs and take nothing for granted. \$\endgroup\$ Commented Jun 20, 2013 at 17:21
0
\$\begingroup\$

I think you need to create a new instance of Camera at the beginning of your method. It looks like you're using the same camera variable for all instances of the Camera, this is unwise and most likely the issue.

Try:

public void CreateCamera()
{
    Camera camera;

    for (int i = 0; i < testCamera.Count; i++)
    {
        camera = new Camera();

        camera = Instantiate(gameObject.AddComponent<Camera>(), new Vector3(0, 0, 0), Quaternion.identity) as Camera;
        camera.name = testCamera[i].Name;
        camera.near = Convert.ToSingle(testCamera[i].Near);
        camera.far = Convert.ToSingle(testCamera[i].Far);
        camera.aspect = Convert.ToSingle(testCamera[i].AspectRatio);
        camera.fov = Convert.ToSingle(testCamera[i].FOV);
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Thanks man, tried this but I still get the same errors as those I listed above. \$\endgroup\$
    – N0xus
    Commented Jun 20, 2013 at 15:19
0
\$\begingroup\$

Create a public variable called CameraPrefab of Camera type in your script, set it equal to null. Then in the editor, select the object that has the script you added CameraPrefab to.

You'll see your script in the inspector, and the CameraPrefab variable with None (Camera) as the value.

enter image description here

Drag the camera prefab you want to instantiate onto the CameraPrefab variable. You should now see None (Camera) replaced with the name of your prefab.

Now when you want to Instantiate an instance of that prefab, you just do the following:

camera = Instantiate(CameraPrefab, new Vector3(0, 0, 0), Quaternion.identity) as Camera;

Instantiate(doc) is used to create an instance of a prefab. Essentially a clone of the object.

Using gameObject.AddComponent<Camera>() doesn't work because only one camera component per object is allowed.

\$\endgroup\$
3
  • \$\begingroup\$ I'm not trying to instantiate a prefab mate. My settings file holds all the camera information and I'm wanting Unity to create a new camera based the settings file. It doesnt need to be attached to anything. \$\endgroup\$
    – N0xus
    Commented Jun 20, 2013 at 15:58
  • \$\begingroup\$ Though if I was to do it another way, that is how I would do it. Thank you anyway :) \$\endgroup\$
    – N0xus
    Commented Jun 20, 2013 at 15:58
  • \$\begingroup\$ @N0xus See Tetrad's answer. It's essentially the same thing except it's not using a prefab, it's just creating a new gameobject at run time. I assumed you wanted a prefab because you were using Instantiate. \$\endgroup\$
    – House
    Commented Jun 20, 2013 at 17:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .