-1
\$\begingroup\$
using UnityEngine;
using System.Collections;

public class SphereObj : MonoBehaviour {

    private GameObject manager;


    void Awake () {
        //things
    }

    public void SetParent(GameObject myManager) {
        manager = myManager;
    }
}

test

using UnityEngine;
using System.Collections;


public class SphereManager : MonoBehaviour {

    int position;
    int detail;

    public GameObject preSphere;

    void Start () {

        for(int i = 0; i < detail; i++){
            SphereObj itsMe = Instantiate(preSphere, new Vector3(0, 0, 0), Quaternion.identity) as SphereObj;
            itsMe.SetParent(gameObject);

        }
    }
}

So im building a game with basicly an unlimited amout of spheres and im instantiating all from a prefab. the prefabs got the first script attached managing sphere stuff, but i want them to have access to variables from the manager script, which is linked to an empty gameobject spawning things. my plan was to link the manager to the sphere scripts by this function:

itsMe.SetParent(gameObject);

but im geting this error

NullReferenceException: Object reference not set to an instance of an object

refering to the line mentioned above.

please help

thanks ahead.

\$\endgroup\$
  • 1
    \$\begingroup\$ The only explanation I could come up with is that you forgot to assign a prefab to the preSphere field of the SphereManager component in the inspector. \$\endgroup\$ – Philipp Sep 15 '16 at 13:26
  • \$\begingroup\$ @Philipp tanks for the reply but the programm works perfectly when removing the evil line. of course it doesnt do anything but spawning a set amout of spheres \$\endgroup\$ – Pentagonpants Sep 15 '16 at 13:31
  • \$\begingroup\$ I don't see anywhere in the code where you set a value / reference for the variable gameObject \$\endgroup\$ – Pikalek Sep 15 '16 at 13:53
  • \$\begingroup\$ @Pikalek gameObject is always the Object the script is linked to, its default by unity. \$\endgroup\$ – Pentagonpants Sep 15 '16 at 13:57
  • \$\begingroup\$ Debug.Log is your friend. Try checking if itsMe is null before calling itsMe.SetParent. If it is null then have Debug.Log print a message. If the application runs fine without calling itsMe.SetParent then it has to be itsMe is null. Which means Instantiate is not creating a SphereObj but some other type instead. \$\endgroup\$ – Dunk Sep 15 '16 at 18:18
0
\$\begingroup\$

You can not explicitly cast an Object as a Component

Instantiate() returns an Object, where you state return as SphereObj. Your attempting to return an Object as a SphereObj, which is not allowed. It is also important to note that SphereObj is derived from your newly created object, despite the fact that it is a component. For this to work, you must ensure that the game object referenced with preSphere contains a SphereObj component.

Use GetComponent<>() to retrieve a Component from a GameObject

Instead, try explicitly casting the return as a GameObject, and appending a GetComponent<> inline.

SphereObj itsMe = 
        (Instantiate(preSphere, new Vector3(0, 0, 0), Quaternion.identity) 
        as GameObject).GetComponent<SphereObj>();

itsMe.SetParent(gameObject);

By explicitly returning the game reference as a GameObject, you are able to retrieve the SphereObj component, and set it up as intended.

The objects instantiate with no issue, and correctly identify the manager as their "parent".


Further Thoughts

You describe setting up a "sphere manager", in a context where there would only logically be one "sphere manager". Perhaps it might be easier, in the long run, to set this up as a singleton-styled script.

class SphereManager
{
    public static SphereManager selfReference;

    void OnStart()
    {
        selfReference = this;
    }
}

In the above example, I create a class that holds a static self reference. This self reference sets itself up during OnStart(), but presuming I only ever have one instance of SphereManager, I do not have an issue with future instances potentially breaking my reference.

I can now call SphereManager.selfReference from anywhere in my code, to access this single instance I have running in my scene. Without having to use the SetParent() function in your SphereObj, you could still call SphereManager.selfReference to call to the manager. You could also access it from other classes, if you need to perform any other logic that involves your spheres.

\$\endgroup\$
  • 1
    \$\begingroup\$ If you define the public variable preSphere to be of type SphereObj then you can write SphereObj itsMe = Instantiate<SphereObj>(preSphere); without a separate GetComponent call. ((SphereObj)Instantiate(preSphere, position, orientation) works too if you need to initialize this transform info). This still spawns the whole object as before, and makes the dependency on the SphereObj component visible in the Inspector, so the Unity editor won't let us accidentally assign a prefab lacking this component. :) \$\endgroup\$ – DMGregory Sep 16 '16 at 3:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.