社交功能
社交系统提供实时聊天、公会、带有状态跟踪的好友以及玩家间的怪物/物品交易。所有服务均使用 Nakama 的内置社交 API(Groups、Friends、Chat channels)和实时匹配(用于交易)。
架构概览
| 类 | 文件 | 职责 |
|---|---|---|
ChatService | Social/SocialServices.cs | 支持 7 种频道类型的实时聊天 |
GuildService | Social/SocialServices.cs | 通过 Nakama Groups 实现公会增删改查、角色、成员管理 |
FriendService | Social/SocialServices.cs | 好友列表、状态跟踪、屏蔽 |
TradeService | Social/SocialServices.cs | 带有服务器验证状态机的 P2P 交易 |
通过 NakamaManager.Instance 访问:
var chat = NakamaManager.Instance.Chat;
var guilds = NakamaManager.Instance.Guilds;
var friends = NakamaManager.Instance.Friends;
var trade = NakamaManager.Instance.Trade;
聊天系统
ChatService 使用 Nakama 的频道消息系统实现了一个多频道实时聊天系统。
频道类型
ChatChannel 枚举定义了 7 种频道类型:
| 频道 | 描述 |
|---|---|
Global | 全服务器公开聊天 |
Local | 附近玩家可见(同一地图/区域) |
Trade | 经济和交易讨论 |
Guild | 仅公会消息 |
Whisper | 私密 1 对 1 直接消息 |
System | 服务器公告和通知 |
Battle | 战斗相关通信 |
加入频道
全局频道在连接期间通过 JoinGlobalChannelAsync() 自动加入。它使用 Nakama 的 Room 类型频道并启用持久化:
// 连接时自动加入 -- 但也可以手动调用
await chat.JoinGlobalChannelAsync();
发送消息
// 发送到公共频道
await chat.SendMessageAsync(ChatChannel.Global, "Hello everyone!");
await chat.SendMessageAsync(ChatChannel.Trade, "WTB: Rare Candy x10");
// 悄悄话(直接消息)
await chat.SendMessageAsync(ChatChannel.Whisper, "Hey!", targetId: recipientUserId);
悄悄话使用 Nakama 的 DirectMessage 频道类型。服务在发送前会自动与目标用户加入 DM 频道。
接收消息
chat.OnMessageReceived += (ChatMessage msg) =>
{
// msg.SenderId, msg.SenderName, msg.Content
// msg.Channel (ChatChannel enum), msg.Timestamp
};
// 访问消息历史(上限为 ChatHistoryCount)
IReadOnlyList<ChatMessage> history = chat.History;
消息历史记录上限为 OnlineConfig.ChatHistoryCount(默认:50)。超出上限时,最旧的消息会被移除。
频道事件
chat.OnChannelJoined += (ChatChannel channel) =>
{
Debug.Log($"Joined {channel} channel");
};
清理
所有频道在断开连接时退出:
await chat.LeaveAllChannelsAsync();
公会系统
GuildService 使用 Nakama 的 Groups API 管理公会(团队/俱乐部)。
创建公会
GuildInfo guild = await guilds.CreateGuildAsync(
name: "Team Rocket",
tag: "TR",
description: "Prepare for trouble!");
// guild.Id, guild.Name, guild.Tag, guild.MemberCount, guild.MaxMembers
每个公会的最大成员数:OnlineConfig.MaxGuildMembers(默认:50)。
加入和离开
bool joined = await guilds.JoinGuildAsync(guildId);
bool left = await guilds.LeaveGuildAsync();