Camera.Main Is Null When Performing Raycast

Camera.main is null when performing raycast

The only thing that can return null in your code is Camera.main.ScreenToWorldPoint. It means that Camera.main is null. For Camera.main to be initialized, the camera must have the MainCamera tag.

Select the Camera GameObject then change the tag to MainCamera.

Sample Image

If you don't want your camera to be in the MainCamera tag, you can also find wit directly with GameObject.Find then get the Camera component from it.

Camera cam;

void Start()
{
cam = GameObject.Find("NameOfCameraGameObject").GetComponent<Camera>();
}

void Update()
{
if (Input.touchCount > 0)
{
RaycastHit2D hit = Physics2D.Raycast(cam.ScreenToWorldPoint(Input.GetTouch(0).position), Vector2.zero);
if (hit && hit.collider != null && hit.collider.name == "leftTapArea")
{
hit.transform.name = "Hit";
}
}
}

Raycast is not hitting what I click

The only time you should ever use the RaycastHit variable returned by the Physics.Raycast function is when Physics.Raycast returns true. If Physics.Raycast returns false, don't bother using or checking the RaycastHit value because it will always be null. Again, hit.transform would be null if Physics.Raycast returns false so you must use the result only when the raycast actually hits something.

Your function can be simplified into something below (notice how result is used in the if statement and only if it returns true):

private bool isPlayerClicked()
{
if (Input.GetMouseButton(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 100, Color.green, 100f); // only draws once. Re-clicking does nothing
Debug.Log("mouse clicked");
if (Physics.Raycast(ray, out hit) && hit.transform.CompareTag("Player"))
{
Debug.Log("Player clicked " + hit.transform.name);
return true;
}
}
return false;
}

Since you just want to detect clocks on a 3D GameObject, use the EventSystem. The OnPointerClick function with the IPointerClickHandler interface should be fine for this. See #6 from this post for how to set this up. This will work on both mobile and desktop platforms.

Raycast returns null for no apparent reason

Don't use Camera.current!

From the API

The camera we are currently rendering with, for low-level render control only (Read Only).

Most of the time you will want to use Camera.main instead. Use this function only when implementing one of the following events: MonoBehaviour.OnRenderImage, MonoBehaviour.OnPreRender, MonoBehaviour.OnPostRender.


So instead use Camera.main

The first enabled camera tagged "MainCamera" (Read Only).

Also note

The primary Camera in the Scene. Returns null if there is no such camera in the Scene. This property uses FindGameObjectsWithTag internally and doesn't cache the result. It is advised to cache the return value of Camera.main if it is used multiple times per frame.

So make sure the camera is tagged MainScene, aktive and than you should use this also only once to get the reference and re-use it like

private Camera _mainCamera;

private void Awake ()
{
_mainCamera = Camera.main;

//Maybe a check
if(!_mainCamera)
{
Debug.LogError("No MainCamera in Scene!");
enabled = false;
}
}

void Update()
{
// ...

ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
Debug.Log(ray);
}

NullReferenceException on Unity

Try checking if you hit something first

if (Input.GetMouseButtonDown(0)) 
{
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
if(hit.collider != null)
{
Debug.Log(hit.transform.name);
}

}


Related Topics



Leave a reply



Submit