You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2D预制体脚本中如何正确引用相机?

问题:Unity相机引用失败,抛出NullReferenceException错误

我在项目中创建了名为Tim的玩家预制体,将Gun_Control脚本挂载在玩家的子物体枪械对象上,尝试在该脚本中引用各类GameObject和Transform。目前遇到的问题是无法正确引用相机,尝试多种方法均无效,控制台抛出「NullReferenceException: Object reference not set to an instance of an object」错误。

当前脚本在Start方法中通过GameObject.FindWithTag("Camera").GetComponent<Camera>()获取相机,且相机已正确设置「Camera」标签;后续尝试使用Camera.main时,Debug.Log输出结果为null。以下是我的脚本代码:

public class Gun_Control : MonoBehaviour
{
// References for GameObjects
[SerializeField] private Rigidbody2D rb;
private GameObject Player;
[SerializeField] private Transform PlayerTransform;
private GameObject Gun;
[SerializeField] private Transform GunTransform;
private Camera MainCamera;
private GameObject firePoint;
[SerializeField] private Transform firePointTransform;
[SerializeField] private GameObject bulletPrefab;

// Variables for Shooting
private Vector2 mousePos;
private float bulletForce = 20f;

// Start is called at the beginning
void Start()
{
    Debug.Log("Starting");
    Player = GameObject.FindWithTag("Player");
    PlayerTransform = Player.transform;
    Gun = GameObject.FindWithTag("PlayerGun");
    GunTransform = Gun.transform;
    MainCamera = GameObject.FindWithTag("Camera").GetComponent<Camera>();
    firePoint = GameObject.FindWithTag("PlayerFirePoint");
    firePointTransform = firePoint.transform;
}

// Update is called once per frame
void Update()
{
    // Get mouse position
    mousePos = MainCamera.ScreenToWorldPoint(Input.mousePosition);

    // Run shoot function on left click
    if(Input.GetButtonDown("Fire1"))
    {
        Shoot();
    }
}

// Update is called on every physics frame
void FixedUpdate()
{
    // Set gun position to player position
    GunTransform.position = PlayerTransform.position;
    // Set gun rotation to mouse position
    Vector2 lookDir = mousePos - rb.position;
    float angle = Mathf.Atan2(lookDir.y ,lookDir.x) * Mathf.Rad2Deg - 180f;
    rb.rotation = angle;
}

void Shoot()
{
    // Instantiate a bullet at the firepoint and give it force
    GameObject bullet = Instantiate(bulletPrefab, firePointTransform.position, firePointTransform.rotation);
    Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
    rb.AddForce(firePointTransform.up * bulletForce, ForceMode2D.Impulse);
}
}
解决方案
  • 修正Camera.main的标签要求:Camera.main仅会返回带有**「MainCamera」系统默认标签**的相机,而非你自定义的「Camera」标签。若要使用Camera.main,需将相机的标签改为「MainCamera」。
  • 改用Inspector直接赋值(最可靠):将private Camera MainCamera;修改为[SerializeField] private Camera MainCamera;,然后在Unity编辑器中直接将相机拖拽到脚本的对应字段上,彻底规避运行时查找的不确定性。
  • 调整查找时机或场景对象状态:
    • 若相机是场景加载后才激活,可将相机获取逻辑移至Awake方法,或确保相机在场景加载时处于激活状态;
    • 若预制体是运行时动态实例化的,可在Update中做延迟检查获取:
      void Update()
      {
          if (MainCamera == null)
          {
              MainCamera = GameObject.FindWithTag("Camera")?.GetComponent<Camera>();
              if (MainCamera != null) Debug.Log("相机引用成功");
          }
          // 原有逻辑...
      }
      
  • 检查同标签相机数量:若场景中存在多个设置了「Camera」标签的相机,GameObject.FindWithTag仅会返回第一个匹配对象,可能不是你需要的目标相机,导致后续组件获取失败。

内容的提问来源于stack exchange,提问作者SKYZE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:40:19