Unity第三人称射击游戏RayCast空引用错误排查求助
第三人称射击游戏射线功能空引用错误排查与修复
问题详情
开发第三人称射击游戏时,实现从屏幕中心发射射线并以小球标记落点的功能,持续触发Object reference is not set to an instance of an object错误,报错代码行:Ray ray = cam.ScreenPointToRay(screenCenterPoint)。尝试替换为Camera.main.ScreenPointToRay后,问题仍未解决。
问题代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using Cinemachine; public class Camera : MonoBehaviour { public Transform orientation; public Transform player; public Transform playerObj; public Rigidbody rb; public float rotationSpeed; [SerializeField] private LayerMask aimColliderLayerMask = new LayerMask(); [SerializeField] private Transform debugTransform; public CameraStyle currentStyle; UnityEngine.Camera cam; public Transform CombatLookAt; public enum CameraStyle { Basic, Combat } void Start() { currentStyle = CameraStyle.Combat; Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } // Update is called once per frame void Update() { Vector3 viewDir = player.position - new Vector3(transform.position.x, player.position.y, transform.position.z); orientation.forward = viewDir.normalized; if (currentStyle == CameraStyle.Basic) { float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); Vector3 inputDir = orientation.forward * verticalInput + orientation.right * horizontalInput; if (inputDir != Vector3.zero) { playerObj.forward = Vector3.Slerp(playerObj.forward, inputDir.normalized, Time.deltaTime * rotationSpeed); } } else if (currentStyle == CameraStyle.Combat) { Vector3 dirToCombatLookAt = CombatLookAt.position - new Vector3(transform.position.x, CombatLookAt.position.y, transform.position.z); orientation.forward = dirToCombatLookAt.normalized; playerObj.forward = dirToCombatLookAt.normalized; } Vector2 screenCenterPoint = new Vector2(Screen.width / 2, Screen.height / 2); Ray ray = cam.ScreenPointToRay(screenCenterPoint); if(Physics.Raycast(ray, out RaycastHit raycastHit, 999f, aimColliderLayerMask)) { transform.position = raycastHit.point; debugTransform.position = raycastHit.point; } } }
解决方案
核心原因
- 代码中声明的
cam字段未初始化,调用其方法时触发空引用。 - 使用
Camera.main时,场景中可能没有Camera标记为MainCamera,或存在多个标记为MainCamera的相机,导致无法正确获取。
修复方案
方案1:初始化cam字段
在Start()方法中添加代码,获取当前脚本挂载对象上的Camera组件:
void Start() { currentStyle = CameraStyle.Combat; Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; // 初始化相机引用 cam = GetComponent<UnityEngine.Camera>(); }
方案2:确保Camera.main有效
- 打开场景中的相机对象,在Inspector面板的Tag下拉菜单选择
MainCamera,且保证场景中仅有一个相机使用该标签。 - 若使用Cinemachine虚拟相机,可直接获取CinemachineBrain的输出相机:
// 先在脚本中添加字段 [SerializeField] private CinemachineBrain cinemachineBrain; void Start() { currentStyle = CameraStyle.Combat; Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; // 获取Cinemachine输出的相机 cam = cinemachineBrain.OutputCamera; }
额外优化建议
- 脚本命名冲突:当前脚本名为
Camera,与Unity内置类重名,建议改为CameraController或其他名称,避免潜在的命名混淆。 - 检查
debugTransform是否已在Inspector面板赋值,防止后续出现新的空引用错误。
内容的提问来源于stack exchange,提问作者JaketheJeff
相关产品推荐
相关产品推荐

