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

如何在Unity中借助Firebase实时数据库实现在线状态检测?

嘿,这个需求我之前做多人游戏的时候刚好折腾过,用Firebase的实时数据库就能完美搞定在线/离线状态的实时同步,下面给你一步步拆解怎么在Unity里实现:

在Unity中用Firebase实现玩家在线/离线状态展示

1. 前置准备

  • 确保你的Unity项目已经集成Firebase Authentication和Firebase Realtime Database(如果偏好Firestore也可以,不过实时数据库对状态同步的支持更直接)
  • 每个玩家登录后会拿到唯一的User ID,这是后续标识玩家身份的核心依据

2. 实现玩家在线状态自动上报

当玩家成功登录后,我们需要把他的在线状态写入数据库,并且利用Firebase的OnDisconnect特性,实现断开连接(包括退出游戏、网络中断)时自动标记为离线,不用手动处理各种异常场景。

核心代码示例(C#)

using Firebase;
using Firebase.Auth;
using Firebase.Database;
using UnityEngine;

public class PlayerPresenceManager : MonoBehaviour
{
    private FirebaseAuth _auth;
    private FirebaseUser _currentUser;
    private DatabaseReference _playerPresenceRef;

    void Start()
    {
        // 初始化Firebase Auth并监听登录状态变化
        _auth = FirebaseAuth.DefaultInstance;
        _auth.StateChanged += OnAuthStateChanged;
        OnAuthStateChanged(this, null);
    }

    void OnAuthStateChanged(object sender, System.EventArgs eventArgs)
    {
        if (_auth.CurrentUser != _currentUser)
        {
            bool isSignedIn = _currentUser != _auth.CurrentUser && _auth.CurrentUser != null;
            
            if (!isSignedIn && _currentUser != null)
            {
                Debug.Log("玩家已登出");
            }
            
            _currentUser = _auth.CurrentUser;
            if (isSignedIn)
            {
                Debug.Log($"玩家 {_currentUser.UserId} 已登录");
                SetupPresenceTracking();
            }
        }
    }

    void SetupPresenceTracking()
    {
        // 指向数据库中存储玩家状态的节点,比如 /presences/{userId}
        _playerPresenceRef = FirebaseDatabase.DefaultInstance.GetReference($"presences/{_currentUser.UserId}");

        // 先标记当前状态为在线
        _playerPresenceRef.SetValueAsync(true);

        // 设置断开连接时自动将状态改为离线
        _playerPresenceRef.OnDisconnect().SetValueAsync(false);
    }

    void OnDestroy()
    {
        if (_auth != null)
        {
            _auth.StateChanged -= OnAuthStateChanged;
        }
        // 主动登出时手动标记离线(可选,OnDisconnect也会处理)
        if (_currentUser != null && _playerPresenceRef != null)
        {
            _playerPresenceRef.SetValueAsync(false);
        }
    }
}

3. 监听其他玩家的状态变化

接下来需要监听数据库中所有玩家的状态节点,实时获取在线/离线更新,然后同步到游戏UI上。

监听与UI更新代码示例

void StartListeningToPlayerPresences()
{
    DatabaseReference presencesRoot = FirebaseDatabase.DefaultInstance.GetReference("presences");

    // 监听所有玩家状态的变化(新增、修改、删除)
    presencesRoot.ValueChanged += (sender, args) =>
    {
        if (args.DatabaseError != null)
        {
            Debug.LogError($"监听状态出错: {args.DatabaseError.Message}");
            return;
        }

        // 遍历所有玩家的状态数据
        foreach (var playerSnapshot in args.Snapshot.Children)
        {
            string userId = playerSnapshot.Key;
            bool isOnline = playerSnapshot.Value as bool? ?? false;

            // 这里可以根据userId拉取玩家的昵称、头像等信息(假设你有/user/{userId}节点存储这些数据)
            // 然后更新UI,比如给在线玩家头像加绿色标识,或者维护在线玩家列表
            UpdatePlayerPresenceUI(userId, isOnline);
        }
    };
}

// 示例:更新玩家状态UI的方法
void UpdatePlayerPresenceUI(string userId, bool isOnline)
{
    // 假设你有一个字典存储玩家对应的UI元素,或者根据userId找到对应的UI对象
    // PlayerStatusUI statusUI = PlayerUIMap[userId];
    // statusUI.SetOnlineIndicator(isOnline);
    Debug.Log($"玩家 {userId} 当前状态: {(isOnline ? "在线" : "离线")}");
}

4. 实用优化建议

  • 关联玩家信息:建议在数据库中单独创建/users/{userId}节点存储玩家昵称、头像URL等信息,这样展示状态时可以显示真实玩家信息,而不是冷冰冰的ID
  • 权限控制:一定要在Firebase控制台设置数据库规则,避免恶意修改状态。示例规则:
{
  "rules": {
    "presences": {
      "$userId": {
        ".read": true,
        ".write": "$userId === auth.uid"
      }
    },
    "users": {
      "$userId": {
        ".read": true,
        ".write": "$userId === auth.uid"
      }
    }
  }
}
  • 网络异常处理:可以添加数据库连接状态监听,当网络恢复时重新同步状态,提升稳定性
  • Firestore替代方案:如果用Firestore,可以用FieldValue.ServerTimestamp()记录最后在线时间,通过判断时间差来识别在线状态,但实时性不如Realtime Database的OnDisconnect直接

内容的提问来源于stack exchange,提问作者Uzoigwe Clement Ikechukwu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:41:38