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.
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
Linq to Entities Doesn't Recognize a Method
What Is the Best Practice for "Copy Local" and with Project References
How to Find All the Classes Which Implement a Given Interface
Getting Downloads Folder in C#
Cannot Implicitly Convert Type 'Int' to 'T'
How to List All Loaded Assemblies
Set Cultureinfo in ASP.NET Core to Have a . as Currencydecimalseparator Instead of ,
How to Communicate with a Windows Service
How to Fix "The Connectionstring Property Has Not Been Initialized"
Checking File/Folder Access Permission
Use of "This" Keyword in Formal Parameters for Static Methods in C#
Difference Between Lookup() and Dictionary(Of List())
Determine Assembly Version During a Post-Build Event
Comparing Timer with Dispatchertimer
Declaring a Variable Inside or Outside an Foreach Loop: Which Is Faster/Better
Entity Framework - Retrieve Id Before 'Savechanges' Inside a Transaction
Memory Efficiency and Performance of String.Replace .Net Framework