Unity中出现NullReferenceException异常,求修复方案
修复Unity NetworkDriver空引用异常方案
问题定位
从错误栈可以看出,空引用异常发生在Server.SendToClient调用driver.BeginSend时,底层NativeList的安全检查失败,核心原因是Server在消息处理流程中提前调用了Shutdown释放NetworkDriver资源,导致后续发送消息时使用了已失效的驱动实例。
具体触发路径:
收到客户端断开事件→调用Shutdown()释放driver→当前消息处理回调(如NetWelcome.ReceivedOnServer)仍在执行→调用SendToClient时使用已被Dispose的driver→触发空引用。
修复步骤
1. 修正断开连接时的Shutdown调用逻辑
移除UpdateMessagePump中Disconnect分支的直接Shutdown调用,改为延迟执行(仅本地游戏场景),确保当前消息处理流程完成后再释放资源:
else if (cmd == NetworkEvent.Type.Disconnect) { Debug.Log("Client disconnected from server"); connections[i] = default(NetworkConnection); connectionDropped?.Invoke(); // 仅本地游戏时延迟关闭,避免当前帧内资源被提前释放 if (isLocal) { Invoke(nameof(Shutdown), 0.1f); } }
2. 给SendToClient添加安全防护
在发送消息前检查服务器状态和连接有效性,避免无效调用:
public void SendToClient(NetworkConnection connection, NetMessage msg) { // 检查服务器是否活跃、连接是否有效 if (!isActive || !connection.IsCreated) { Debug.LogWarning("无法发送消息:服务器已关闭或连接无效"); return; } DataStreamWriter writer; driver.BeginSend(connection, out writer); msg.Serialize(ref writer); driver.EndSend(writer); }
3. 调整Shutdown执行顺序
先标记服务器为非活跃状态,再释放资源,阻止后续操作访问已释放的驱动:
public void Shutdown() { if (isActive) { isActive = false; // 先阻止后续操作 driver.Dispose(); connections.Dispose(); } }
额外建议
- 检查
NetWelcome.ReceivedOnServer和Chessboard.OnWelcomeServer中的逻辑,确保发送响应前连接状态正常 - 可以在
Broadcast方法中同样添加isActive检查,避免服务器关闭后仍尝试广播消息
内容的提问来源于stack exchange,提问作者Bitpoke
相关产品推荐
相关产品推荐

