Unity通过命令调用器执行画线命令时出现Camera空引用异常
问题解决:Unity命令模式调用画线时的NullReferenceException异常
核心问题分析
你遇到的异常根源是DrawLineCommand的MyLine字段未正确赋值:直接调用命令时你手动给MyLine赋了有效引用,但通过CommandInvoker调用时遗漏了这一步,导致Execute()中调用MyLine.InitLine()触发空引用。同时Line类的Update方法存在未判空的潜在问题,让你误以为是Camera的异常。
分步修复方案
1. 修复DrawLineCommand的参数传递
修改DrawLineCommand.cs,通过构造函数强制传入Line实例,从根源避免空引用:
using UnityEngine; public class DrawLineCommand : ICommand { private readonly Line _myLine; // 构造函数接收Line实例,确保引用有效 public DrawLineCommand(Line line) { _myLine = line; Debug.Log("Draw Line Command initialized"); } public void Execute() { Debug.Log("Executing line command"); if (_myLine == null) { Debug.LogError("Line reference is null in DrawLineCommand"); return; } _myLine.InitLine(); } }
2. 正确添加命令到调用器
在添加命令时,必须传入场景中已存在的Line组件实例:
// 在任意脚本的Start/Init方法中添加命令 void Start() { // 获取场景中已挂载的Line组件 Line lineComponent = FindObjectOfType<Line>(); if (lineComponent != null) { CommandInvoker.AddCommand(new DrawLineCommand(lineComponent)); } else { Debug.LogError("场景中未找到Line组件"); } }
3. 修复Line类的潜在异常点
修改Line.cs,补充判空逻辑并移除不必要的try-catch:
using System.Collections.Generic; using UnityEngine; public class Line : MonoBehaviour { private LineRenderer _lRenderer; private List<Vector3> _Vertices = new List<Vector3>(); public Material material; private void Start() { InitLine(); } private void Update() { if (Input.GetMouseButtonDown(0)) { // 先验证Camera.main有效性 if (Camera.main == null) { Debug.LogError("未找到标记为MainCamera的相机"); return; } Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(camRay, out RaycastHit hit)) { Renderer hitRenderer = hit.transform.GetComponent<Renderer>(); // 判空后再访问name属性 if (hitRenderer != null && hitRenderer.name == "MyGround") { Debug.Log("点击了地面"); // 仅编辑器模式下使用弹窗,避免打包报错 #if UNITY_EDITOR UnityEditor.EditorUtility.DisplayDialog("提示", "点击了MyGround", "确定"); #endif } } } } public void InitLine() { _lRenderer = GetComponent<LineRenderer>(); // 自动添加缺失的LineRenderer组件 if (_lRenderer == null) { Debug.LogWarning("Line组件缺少LineRenderer,自动添加"); _lRenderer = gameObject.AddComponent<LineRenderer>(); } _lRenderer.positionCount = 0; _lRenderer.startWidth = 0.15f; _lRenderer.endWidth = 0.15f; _lRenderer.useWorldSpace = true; _lRenderer.numCapVertices = 50; // 赋值材质(如果已设置) if (material != null) { _lRenderer.material = material; } } }
4. 验证Camera设置
确保场景中的相机Tag已设置为MainCamera:
选中相机对象,在Inspector面板的Tag下拉框中选择"MainCamera",确保Camera.main能正确获取到相机实例。
额外注意事项
- 避免在非编辑器环境下使用
UnityEditor.EditorUtility类,否则打包后会报错。 - 静态队列
CommandBuffer在场景切换时不会自动清空,若需要可在OnDestroy中添加清空逻辑。
内容的提问来源于stack exchange,提问作者joeb
相关产品推荐
相关产品推荐

