Unity Photon多人游戏:非房主重连触发空引用异常
问题原因分析
异常发生在PlayerMovement.Start()方法第22行,对应代码m_camera.enabled = false;,核心原因是非房主玩家的m_camera字段未被初始化,导致空引用:
- 你没有在代码中给
m_camera赋值的逻辑(既没有在Inspector面板绑定,也没有通过代码查找); - 非房主玩家重新加入时,其玩家对象的
m_camera为null,直接访问enabled属性触发NullReferenceException。
另外,你的摇杆查找逻辑存在性能问题:FixedUpdate中每帧调用GameObject.FindGameObjectWithTag会消耗大量性能,且同样存在找不到摇杆导致空引用的风险。
解决方案
1. 修复相机空引用问题
两种可选方式:
- 方式一:Inspector绑定:在Unity编辑器中,将玩家对象的相机组件拖拽到
PlayerMovement脚本的m_camera字段上; - 方式二:代码自动查找:在
Start方法中通过GetComponentInChildren获取子物体上的相机,并添加空判断避免异常。
2. 优化摇杆查找逻辑
将摇杆查找从FixedUpdate移到Start,并添加空判断;推荐将MovementJoystick改为单例模式,进一步提升可靠性和性能。
3. 非本地玩家相机优化(可选)
生成玩家对象时,仅给本地玩家(PhotonView.IsMine为true)添加相机组件,非本地玩家直接不挂载相机,从根源避免空引用。
修改后的代码示例
PlayerMovement.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; public class PlayerMovement : MonoBehaviour { public MovementJoystick movementJoystick; public float playerSpeed; private Rigidbody2D rb; public Camera m_camera; PhotonView view; void Start() { rb = GetComponent<Rigidbody2D>(); view = GetComponent<PhotonView>(); // 自动查找子物体中的相机 m_camera = GetComponentInChildren<Camera>(); // 仅在Start中查找一次摇杆,添加空判断 var joystickObj = GameObject.FindGameObjectWithTag("JoyStick"); if (joystickObj != null) { movementJoystick = joystickObj.GetComponent<MovementJoystick>(); } if (!view.IsMine) { // 空判断避免异常 if (m_camera != null) { m_camera.enabled = false; } } } void FixedUpdate() { // 仅本地玩家执行移动,且确保摇杆不为空 if(view.IsMine && movementJoystick != null) { rb.velocity = movementJoystick.joystickVec.y != 0 ? new Vector2(movementJoystick.joystickVec.x * playerSpeed, movementJoystick.joystickVec.y * playerSpeed) : Vector2.zero; } } }
可选:MovementJoystick单例改造
public class MovementJoystick : MonoBehaviour { public static MovementJoystick Instance; public Vector2 joystickVec; void Awake() { Instance = this; } // 原有摇杆逻辑... }
之后在PlayerMovement中直接通过MovementJoystick.Instance获取摇杆,无需再用FindGameObjectWithTag。
内容的提问来源于stack exchange,提问作者Coralap
相关产品推荐
相关产品推荐

