- Home /
Other
NullReferenceException from GameObject.find
Hello.
So, I'm working on a space RTS game, where I have two levels: one is the galaxy view and another is a system view. I can freely move camera in the galaxy level, and when i click on a star it takes me to the system level. The idea is, that when I click on a star I want to save the camera position in PlayerPrefs using the following code:
void OnMouseUp(){
GameObject RP = GameObject.Find("RotationPoint");
GameObject parent = GameObject.Find("Parent");
Camera Cam = Camera.main;
float RPX = RP.transform.position.x;
float RPY = RP.transform.position.y;
float RPZ = RP.transform.position.z;
float PX = parent.transform.position.x;
float PY = parent.transform.position.y;
float PZ = parent.transform.position.z;
float CX = Cam.transform.position.x;
float CY = Cam.transform.position.y;
float CZ = Cam.transform.position.z;
float RPRX = RP.transform.rotation.x;
float RPRY = RP.transform.rotation.y;
PlayerPrefs.SetFloat("RotPX",RPX);
PlayerPrefs.SetFloat("RotPY", RPY);
PlayerPrefs.SetFloat("RotPZ", RPZ);
PlayerPrefs.SetFloat("ParentX", PX);
PlayerPrefs.SetFloat("ParentY", PY);
PlayerPrefs.SetFloat("ParentZ", PZ);
PlayerPrefs.SetFloat("CamX", CX);
PlayerPrefs.SetFloat("CamY", CY);
PlayerPrefs.SetFloat("CamZ", CZ);
PlayerPrefs.SetFloat("RotX",RPRX);
PlayerPrefs.SetFloat("RotY", RPRY);
}
The problem is, that I get a NullReferenceError in the line with setting the Parent Pref. I've tried severeal things, and I think it's because of the GameObject.find. I also heard that I should avoid using it, but I can't really think of anything else(I've also tried .FindObjectWithTag).
Thanks in advance for all of the answers.
-Xentarok
P.S - My english isn't really good, so I apologize for any mistakes. P.S.2 - If you have any specific questions, write them in the comments.
I realize that this is 2 years old, but your English is great, actually.
Answer by aldonaletto · Oct 06, 2013 at 12:30 PM
1) Yes, you should avoid any Find functions in Update - they are too slow, specially when there are many GameObjects in scene. Declare a public variable and drag the object to it in the Inspector, or Find it only once at Start:
public GameObject RP; // drag the object here in the Inspector...
void Start(){
if (!RP){ // if RP not assigned in the Inspector...
RP = GameObject.Find("RotationPoint"); // Find it
}
}
2) About the Parent: apparently, there's no object named "Parent" in scene, thus Find returns null and originates this error - check its capitalization ("parent" isn't the same as "Parent"). Or are you trying to access the parent of some object? If so, that's the wrong way: someObj.transform.parent gives you the parent of someObj :
void Update(){
Transform rpParent = RP.transform.parent;
...
3) transform.rotation is a Quaternion, not those nice angles we see under Rotation in the Inspector (they are actually the transform.eulerAngles ). Anyway, saving only X and Y won't work fine in both cases: you must save all XYZW components of rotation, or XYZ of eulerAngles. By the way, you can save stuff in a much easier and efficient way - like below:
// cache the properties in temporary variables:
Vector3 rpPos = RP.transform.position;
Vector3 pPos = parent.transform.position;
Vector3 camPos = Cam.transform.position;
Quaternion rpRot = RP.transform.rotation;
PlayerPrefs.SetFloat("RotPX", rpPos.x);
PlayerPrefs.SetFloat("RotPY", rpPos.y);
PlayerPrefs.SetFloat("RotPZ", rpPos.z);
PlayerPrefs.SetFloat("ParentX", pPos.x);
PlayerPrefs.SetFloat("ParentY", pPos.y);
PlayerPrefs.SetFloat("ParentZ", pPos.z);
PlayerPrefs.SetFloat("CamX", camPos.x);
PlayerPrefs.SetFloat("CamY", camPos.y);
PlayerPrefs.SetFloat("CamZ", camPos.z);
PlayerPrefs.SetFloat("RotX", rpRot.x); // you must save all rotation components...
PlayerPrefs.SetFloat("RotY", rpRot.y);
PlayerPrefs.SetFloat("RotZ", rpRot.z); // including Z...
PlayerPrefs.SetFloat("RotW", rpRot.w); // and W
NOTE: Remember to restore all components of rotation too!
Thanks for the answer but unfortunetly it doesn't work. This script is attached to a prefab so i can't assign the "Parent" in the inspector, and when I have the .find in the start, it still gives me an error! About 1 nad 2, I have an object called Parent and I only need two elements of the rotation.
You must save the entire rotation or eulerAngles - all the XYZW components of rotation are necessary to define a Quaternion, and the eulerAngles may have weird values in X and Y that are compensated by another weird value in Z: if you set (120,120,0) in the Inspector, for instance, it becomes (60,300,180) when running - if you save only X and Y, the restored angles will become (60,300,0) ins$$anonymous$$d of (120,120,0)!
From the comments you've posted in @Vandash's answer, it seems that RotationPoint and Parent don't exist anymore when you try to save them! Add debug lines to check this:
void On$$anonymous$$ouseUp(){
GameObject RP = GameObject.Find("RotationPoint");
if (!RP) Debug.Log("RotationPoint not found");
GameObject parent = GameObject.Find("Parent");
if (!parent) Debug.Log("Parent not found");
...
If you're about to load another scene, your logic may be wrong and those objects have already been destroyed at On$$anonymous$$ouseUp - try to use On$$anonymous$$ouseDown ins$$anonymous$$d.
Yeah, both of these Debugs were shown, I tried On$$anonymous$$ouseDown but it doesn't work either.
So, these objects don't exist anymore. Check your logic: something is destroying them before.
Answer by David_29 · Jun 07, 2017 at 02:54 AM
Quickfix: if you're using C#, try adding this code using System
at the top of your script or import System
if you're using Javascript. You can now try-catch GameObject.Find
if it returns null. No errors will throw at you.
Here's an example:
using System; // --> This exact line of code. That's it.
using UnityEngine;
public class Test : MonoBehaviour {
public void OnMouseUp() {
// You may now catch null reference here.
try {
GameObject RP = GameObject.Find("RotationPoint");
// The rest of your code here.
} catch(NullReferenceException e) {
}
}
}
Also remember, you can catch also other exceptions such as MissingReferenceException
, MissingComponentException
, IndexOutOfRangeException
, or any other exception classes as long as you include using System
in your script. That is all.
Answer by Vandash · Oct 06, 2013 at 01:10 PM
Do you have a gameobject in your scene called "RotationPoint" and one called "Parent" ? GameObject.Find will look for object names, so you need to make sure these objects actually exist in your scene.
On a side note, you should rename all your variable to give them more reliable names.
I would avoid having one game object called "parent", as the parenting concept is usually used by Unity in transform.parent (which makes your naming confusing), instead try using Root or World or something similar.
Yes, I have an both of these objects, named exactly like in the script.
In your other comment you talked about prefabs. Gameobject.Find will NOT find prefabs (except if they are instanciated in the scene). Could that be the problem ?
No, the script is attached to a instanciated prefab but the objects are in scene by default.
I think you failed at explaining your problem because this sounds like a super simple problem... - Is your parent variable null ? - On what line is your error co$$anonymous$$g exactly ?
As I said before, the error comes from the line where i set the float to the position on x axis of parent which is a GamaObject defined by GameObject.Find, and since I don't get that error from the Camera (Cam) I assume that it's a problem with gameobject.find.
Follow this Question
Related Questions
RTS Mouse Click Movement 1 Answer
SmoothDamp bounce effect 0 Answers
RTS game: Camera movement is wierd 2 Answers
3D RTS camera 3 Answers
How to save progress in the game? 1 Answer