Toxic Cookie
Toxic Cookie

Reputation: 83

Raycast returns null for no apparent reason

Ok, so quick question, I made a simple:

Ray ray;

Then in the update() I made a simple:

ray = Camera.current.ScreenPointToRay(Input.mousePosition);
Debug.Log(Camera.current.ScreenPointToRay(Input.mousePosition));

And for some reason, in the console, the debug.log registers a ray being casted while ray just thinks it's null.

Any ideas?

This is the debug.log output:

Origin: (-0.2, 2.5, 14.8), Dir: (-0.4, 0.5, -0.7)
Unity.engine.Debug:Log(Object)
TankController:Update() (at Assets/Games/Chisana/Scripts/TankController.cs:136)

This is the ray output:

NullReferenceException: Object reference not set to an instance of an object
TankController.Update() (at Assets/Games/Chisana/Scripts/TankController.cs:135)

In case I overlooked something, here's the full script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TankController : MonoBehaviour
{
    Vector3 targetPosition;
    Vector3 lookAtTarget;

    public Vector4 selectedColor;
    public Vector4 deselectedColor;

    Quaternion playerRot;

    public float rotSpeed = 2;
    public float speed = 3;

    bool OneExecution = false;
    int count = 0;

    public bool Moving = false;
    public bool Selected = false;
    public bool UiSelected = false;
    public bool Hovering = false;

    public GameObject UI;
    public BoxCollider HitBox;

    public DoEverything Properties;
    public GameObject childObj;

    public MeshRenderer mrHighlight;

    public PlayerMaster playerMaster;
    int playerMasterTeam;

    SkinnedMeshRenderer[] skinnedMeshRenderersScan;
    public List<SkinnedMeshRenderer> skinnedMeshRenderersList = new List<SkinnedMeshRenderer>();

    Ray ray;
    RaycastHit hit;

    void Start()
    {
        Properties = GetComponentInChildren<DoEverything>(); //Get the DoEverything script

        childObj = Properties.InstancedEntity; //Get the object it will spawn

        if (mrHighlight.enabled != false && mrHighlight != null) //Make sure the highlight isn't enabled and not null
        {
            mrHighlight.enabled = false;
        }

        skinnedMeshRenderersScan = childObj.GetComponentsInChildren<SkinnedMeshRenderer>(); //Looks for all skinned mesh renderers in child object

        foreach (SkinnedMeshRenderer element in skinnedMeshRenderersScan) //For every object it finds
        {
            if (!skinnedMeshRenderersList.Contains(element)) //If it isn't already in this list
            {
                skinnedMeshRenderersList.Add(element); //Add to the list
            }
        }

        playerMasterTeam = playerMaster.Team;
    }

    void LClickRay()
    {

    }

    void RClickRay()
    {

    }

    void OnMouseEnter()
    {
        Hovering = true;
        foreach (SkinnedMeshRenderer element in skinnedMeshRenderersScan) //For every object it finds
        {
            element.material.color = selectedColor;
        }
    }

    void OnMouseExit()
    {
        Hovering = false;
        foreach (SkinnedMeshRenderer element in skinnedMeshRenderersScan) //For every object it finds
        {
            element.material.color = deselectedColor;
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            Physics.IgnoreCollision(collision.collider, HitBox);
        }
    }

    void Move()
    {
        transform.rotation = Quaternion.Slerp(transform.rotation,
                                                    playerRot,
                                                    rotSpeed * Time.deltaTime);
        transform.position = Vector3.MoveTowards(transform.position,
                                                targetPosition,
                                                speed * Time.deltaTime);

        if (transform.position == targetPosition)
        {
            Moving = false;
        }
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            LClickRay();
        }
        if (Input.GetMouseButtonDown(1))
        {
            RClickRay();
        }

        if (Moving == true)
        {
            Move();
        }

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

Upvotes: 1

Views: 676

Answers (1)

derHugo
derHugo

Reputation: 90639

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);
}

Upvotes: 2

Related Questions