Photon PUN多人FPS游戏Missing Reference Exception问题求助
基于Photon PUN的多人FPS游戏Missing Reference Exception问题解决
问题描述
开发基于Photon PUN的多人FPS游戏时,单人房间运行无报错,但其他玩家加入后,代码在Physics.Raycast(playerCam.position, playerCam.forward, out hit, range)行抛出Missing Reference Exception,错误提示为“你正在访问的transform已被销毁”。已确认playerCam不为空,但问题仍未解决。
相关代码
Shoot协程代码
private IEnumerator Shoot() { ammoLeft -= 1; animator.SetBool("fire", true); RaycastHit hit; if (Physics.Raycast(playerCam.position, playerCam.forward, out hit, range)) { // Missing Reference Expection The transform you are accessing is destroyed // 单人模式下正常运行 if (hit.transform.tag == "Player" && hit.transform != null) { HealthManager HealthScript = hit.transform.gameObject.GetComponent<HealthManager>(); if (HealthScript != null) { HealthScript.TakeDamage(damage); } } } yield return new WaitForSeconds(0.3f); animator.SetBool("fire", false); if (ammoLeft <= 0f) { StartCoroutine("Reload"); } }
Awake方法代码
private void Awake() { if (!pv.IsMine) { Destroy(ui); } if (playerCam == null) { playerCam = FindObjectOfType<Camera>().transform; } ammoLeft = magazineSize; animator = GetComponent<Animator>(); }
问题分析与解决
1. 修正PlayerCam的获取逻辑
FindObjectOfType<Camera>()会遍历场景中所有激活状态的Camera,当其他玩家加入后,可能误获取到其他玩家的Camera(而其他玩家的Camera可能在本地被禁用/销毁)。建议:
- 给本地玩家的Camera添加
MainCamera标签,改用Camera.main.transform获取,确保只拿到自己的主相机:
if (playerCam == null) { playerCam = Camera.main.transform; }
- 或者在本地玩家对象的子节点挂载专属Camera,通过
GetComponentInChildren<Camera>()获取,避免跨对象查找。
2. 确保射击逻辑仅在本地玩家对象执行
Photon中,只有本地玩家的对象应该处理输入和射击逻辑,避免其他玩家的对象在本地执行无效代码。在启动Shoot协程前添加判断:
// 调用Shoot的地方增加校验 if (pv.IsMine) { StartCoroutine(Shoot()); }
3. 安全访问Raycast命中对象
报错提示“transform已销毁”,实际可能是命中的对象已被销毁,但hit.transform仍残留无效引用。访问前先检查hit.collider是否存在(对象销毁后collider会被移除),并调整判断顺序:
if (Physics.Raycast(playerCam.position, playerCam.forward, out hit, range)) { // 先检查collider有效性,再判断标签 if (hit.collider != null && hit.collider.CompareTag("Player")) { HealthManager healthScript = hit.collider.GetComponent<HealthManager>(); if (healthScript != null) { healthScript.TakeDamage(damage); } } }
4. 检查其他玩家对象的销毁逻辑
在Awake中仅销毁非本地玩家的UI组件,不要销毁对象本身或其核心组件(如Transform、Camera)。其他玩家的对象需要保留以同步网络状态,销毁核心组件会导致引用失效。
内容的提问来源于stack exchange,提问作者Malay Joshi
相关产品推荐
相关产品推荐

