Raycast无明显原因返回null

时间:2019-02-25 00:40:05

标签: c# unity3d

好吧,这么简单的问题,我做了一个简单的事情:

Ray ray;

然后在update()中,我做了一个简单的事情:

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

由于某种原因,在控制台中,debug.log注册了正在投射的光线,而ray只是认为它为空。

有什么想法吗?

这是debug.log输出:

  

来源:(-0.2,2.5,14.8),目录:(-0.4,0.5,-0.7)
  Unity.engine.Debug:Log(Object)
  TankController:Update()(位于Assets / Games / Chisana / Scripts / TankController.cs:136)

这是射线输出:

  

NullReferenceException:对象引用未设置为对象的实例
  TankController.Update()(位于Assets / Games / Chisana / Scripts / TankController.cs:135)

如果我忽略了某些内容,请看完整的脚本:

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

1 个答案:

答案 0 :(得分:2)

请勿使用Camera.current

API

  

当前正在渲染的摄像机,仅用于低级渲染控制(只读)。

     

大多数情况下,您将要使用Camera.main。实施以下事件之一时,请使用此功能:MonoBehaviour.OnRenderImageMonoBehaviour.OnPreRenderMonoBehaviour.OnPostRender


因此,请改用Camera.main

  

第一个启用的摄像机标记为“ MainCamera”(只读)。

也请注意

  

场景中的主要摄像机。如果场景中没有此类摄像机,则返回null。此属性在内部使用FindGameObjectsWithTag,并且不缓存结果。如果每帧多次使用,建议缓存Camera.main的返回值。

因此,请确保将相机标记为MainScene,并设置为活跃,然后您也只能使用一次来获取参考并像这样重复使用

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