The most important thing to understand here is that GameObject.FindGameObjectWithTag
, GameObject.Find
and other FindXXX
functions for GameObjects cannot and will not be able to find GameObjects that are not active in the scene.
This is the reason you are getting that error. In most cases, you have two options:
1.Assign player from the Editor:
Make the player variable a public variable then assign the player to the player slot from the Editor.
public GameObject player;
With this, you don't need to use GameObject.FindGameObjectWithTag
again and player cannot be null unless you explicitly set it to null
.
2.If your GameObject has to be In-active by default then make it active from the Editor.
Find it with GameObject.FindGameObjectWithTag
at the begining of the scene in the Start
or Awake
function then quickly set make it in-active with
player.SetActive(false);
.
Finally, Unity does not support finding in-active GameObjects by default but below are the functions once can use to find them. Do not abuse them because they are slow:
Find in-active GameObject by Name:
GameObject FindObjectInActiveByName(string name)
{
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() as Transform[];
for (int i = 0; i < objs.Length; i++)
{
if (objs[i].hideFlags == HideFlags.None)
{
if (objs[i].name == name)
{
return objs[i].gameObject;
}
}
}
return null;
}
Find in-active GameObject by Tag:
GameObject FindObjectInActiveByTag(string tag)
{
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() as Transform[];
for (int i = 0; i < objs.Length; i++)
{
if (objs[i].hideFlags == HideFlags.None)
{
if (objs[i].CompareTag(tag))
{
return objs[i].gameObject;
}
}
}
return null;
}
Find in-active GameObject by Layer:
GameObject FindObjectInActiveByLayer(int layer)
{
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() as Transform[];
for (int i = 0; i < objs.Length; i++)
{
if (objs[i].hideFlags == HideFlags.None)
{
if (objs[i].gameObject.layer == layer)
{
return objs[i].gameObject;
}
}
}
return null;
}
EDIT:
With your more information, the problem is from here Camera.main.ScreenPointToRay
:
If your camera is in-active or your camera is under a GameObject that is in-active, Camera.main
will return null
. It will not be able to find the Camera. When it returns null and you try to call its ScreenPointToRay
function, you get an exception.
Also, if you have another camera in the scene that you toggle to, you have to make sure that you change the tag of that camera to "MainCamera" if that's the camera you use for Raycast
. Check this post for more information on that. You do that because Camera.main
will look for enabled Camera with the "MainCamera" tag.