UE5 SDK 开发指南
本文介绍如何在游戏中加入好友系统。
集成前准备
- 参考 TapTap 好友功能介绍确认选择好友(不含聊天)
- 参考 UE5 集成指南完成 TapSDK 基础接入
- 完成 TapTap 登录,并在登录授权范围中添加
user_friends
权限说明
Android 权限说明
该模块在 Android 平台需要如下权限:
| 权限 | 使用目的 | 权限申请时机 |
|---|---|---|
| 网络权限 | 用于访问网络数据 | 用户首次使用该功能时会申请权限 |
| 网络状态权限 | 用于检查网络连接状态(如 Wi-Fi 或移动数据是否可用) | 用户首次使用该功能时会申请权限 |
| 读取外部存储权限 | 用于读取设备上的文件和媒体内容 | 用户首次使用相关功能时会申请权限 |
| 写入外部存储权限 | 用于保存文件到设备存储 | 用户首次使用文件保存功能时会申请权限 |
| 管理外部存储权限 | 用于管理设备上的文件 | 用户首次使用文件管理功能时会申请权限 |
| 前台服务权限 | 用于在应用处于后台时保持某些功能运行 | 应用需要在后台运行服务时 |
| 相机权限 | 用于拍摄照片和视频通话 | 用户首次使用相机相关功能时会申请权限 |
| 振动权限 | 用于消息通知时的振动提醒 | 应用需要使用振动提醒时 |
该模块将在 Android 应用中添加如下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
SDK 获取
参考 UE5 集成指南完成 TapCore 基础接入。再从下载页下载相同版本的 TapLogin、TapProfile、TapRelationLite,放入项目的 Plugins 目录并启用。
添加模块依赖
在游戏模块的 <GameModule>.Build.cs 中添加:
PublicDependencyModuleNames.AddRange(new string[]
{
"TapCore",
"TapLogin",
"TapProfile",
"TapRelationLite",
});
修改 Build.cs 后重新生成项目文件并编译。
外部唤起工程配置
Android 配置
邀请回到游戏还需要配置 URL Scheme;仅启用插件和注册回调并不够。Scheme 为 tds 加上游戏的 Client ID,与登录使用的 tt{clientId} 不同。
在游戏模块的 Build.cs 同目录创建 TapRelationInvite_UPL.xml,并将 {clientId} 替换为游戏的 Client ID:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<androidManifestUpdates>
<addElements tag="application">
<activity
android:name="com.taptap.sdk.relation.lite.TapRelationLiteRouterActivity"
android:exported="true"
android:noHistory="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="tds{clientId}"
android:host="invite_game" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="tds{clientId}"
android:host="invite_team" />
</intent-filter>
</activity>
</addElements>
</androidManifestUpdates>
</root>
在该模块的 Build.cs 构造函数中注册 UPL:
if (Target.Platform == UnrealTargetPlatform.Android)
{
AdditionalPropertiesForReceipt.Add(
"AndroidPlugin",
System.IO.Path.Combine(ModuleDirectory, "TapRelationInvite_UPL.xml"));
}
打包后检查最终合并的 AndroidManifest.xml 是否包含对应 Activity、Scheme 和两个 host。不要直接修改构建产生的临时 Manifest。
iOS 配置
在最终 Info.plist 的 CFBundleURLTypes 中增加好友邀请 Scheme。可通过 UE5 iOS 工程配置或项目的 UPL 合入;已有登录或其他 URL 类型时,合并数组内容,不要覆盖已有配置:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>TapTapRelationInvite</string>
<key>CFBundleURLSchemes</key>
<array>
<string>tds{clientId}</string>
</array>
</dict>
</array>
将 {clientId} 替换为游戏的 Client ID。好友插件接收 UE5 的打开 URL 事件并转发给原生好友 SDK;业务层仍需注册邀请回调,并处理加入游戏或队伍的逻辑。
注册/注销 统一状态码监听回调
回调对象需要实现 ITapRelationLiteCallback,并重写 OnResult_Implementation()。使用 UPROPERTY() 等方式持有回调对象。
#include "MyRelationLiteCallback.h"
#include "TapRelationLite.h"
void UMyRelationLiteCallback::OnResult_Implementation(int32 Code)
{
// 处理好友状态码
}
// 注册回调
RelationLiteCallback = NewObject<UMyRelationLiteCallback>(this);
TScriptInterface<ITapRelationLiteCallback> Callback;
Callback.SetObject(RelationLiteCallback);
Callback.SetInterface(Cast<ITapRelationLiteCallback>(RelationLiteCallback));
UTapRelationLite::RegisterRelationLiteCallback(Callback);
// 不再接收回调时,使用同一个对象注销
UTapRelationLite::UnregisterRelationLiteCallback(Callback);
注册邀请回调
当玩家点击 TapTap 邀请消息并打开游戏时,SDK 会解析邀请信息,开发者可通过注册该回调获取发起邀请的用户和组队信息。示例如下:
#include "TapRelationLiteCallback.h"
#include "TapRelationLite.h"
UCLASS()
class UMyRelationLiteInviteCallback : public UObject, public ITapRelationLiteInviteCallback
{
GENERATED_BODY()
public:
virtual void OnGameInviteReceived_Implementation(const FString& OpenId, const FString& UnionId) override;
virtual void OnTeamInviteReceived_Implementation(const FString& OpenId, const FString& UnionId, const FString& TeamId) override;
};
void UMyRelationLiteInviteCallback::OnGameInviteReceived_Implementation(
const FString& OpenId,
const FString& UnionId)
{
// 处理邀请上线事件
}
void UMyRelationLiteInviteCallback::OnTeamInviteReceived_Implementation(
const FString& OpenId,
const FString& UnionId,
const FString& TeamId)
{
// 处理邀请组队事件
}
// 注册回调
RelationLiteInviteCallback = NewObject<UMyRelationLiteInviteCallback>(this);
TScriptInterface<ITapRelationLiteInviteCallback> Callback;
Callback.SetObject(RelationLiteInviteCallback);
Callback.SetInterface(Cast<ITapRelationLiteInviteCallback>(RelationLiteInviteCallback));
UTapRelationLite::RegisterRelationLiteInviteCallback(Callback);
// 不再接收回调时,使用同一个对象注销
UTapRelationLite::UnregisterRelationLiteInviteCallback(Callback);
邀请好友上线
打开邀请好友页面,向选中的好友发送邀请上线消息。
UTapRelationLite::InviteGame();
邀请好友组队
打开邀请好友页面,向选中的好友发送邀请组队消息,需要传入组队参数 TeamId。
UTapRelationLite::InviteTeam(TEXT("team_id"));
获取好友列表
获取当前用户的好友列表。
UTapRelationLite::GetFriendsList(
TEXT(""), // 首次请求传空字符串,继续分页时传入上一次返回的 NextPageToken
[](const FTapRelationLiteUserResult& Result)
{
// Result.Users 为好友列表
// Result.NextPageToken 用于请求下一页
UE_LOG(LogTemp, Log, TEXT("Friends: %d"), Result.Users.Num());
},
[](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Load friends failed [%d]: %s"), Code, *Message);
});
获取关注列表
调用 GetFollowingList() 获取当前用户的关注列表。
UTapRelationLite::GetFollowingList(
TEXT(""), // 首次请求传空字符串,继续分页时传入上一次返回的 NextPageToken
[](const FTapRelationLiteUserResult& Result)
{
// Result.Users 为关注列表
// Result.NextPageToken 用于请求关注列表的下一页
UE_LOG(LogTemp, Log, TEXT("Following: %d"), Result.Users.Num());
},
[](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Load following failed [%d]: %s"), Code, *Message);
});
获取粉丝列表
调用 GetFansList() 获取当前用户的粉丝列表。
UTapRelationLite::GetFansList(
TEXT(""), // 首次请求传空字符串,继续分页时传入上一次返回的 NextPageToken
[](const FTapRelationLiteUserResult& Result)
{
// Result.Users 为粉丝列表
// Result.NextPageToken 用于请求粉丝列表的下一页
UE_LOG(LogTemp, Log, TEXT("Fans: %d"), Result.Users.Num());
},
[](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Load fans failed [%d]: %s"), Code, *Message);
});
同步好友关系(openId)
使用好友 openId 将好友关系同步至 TapTap。
// 1-新增好友,2-删除好友
int32 Action = 1;
// 当前用户昵称
FString Nickname = TEXT("");
// 好友用户昵称
FString FriendNickname = TEXT("");
// 好友 openId
FString FriendOpenId = TEXT("");
UTapRelationLite::SyncRelationshipWithOpenId(
Action,
Nickname,
FriendNickname,
FriendOpenId,
[]()
{
UE_LOG(LogTemp, Log, TEXT("Relationship synced"));
},
[](const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Sync failed: %s"), *Message);
});
同步好友关系(unionId)
使用好友 unionId 将好友关系同步至 TapTap。
// 1-新增好友,2-删除好友
int32 Action = 1;
// 当前用户昵称
FString Nickname = TEXT("");
// 好友用户昵称
FString FriendNickname = TEXT("");
// 好友 unionId
FString FriendUnionId = TEXT("");
UTapRelationLite::SyncRelationshipWithUnionId(
Action,
Nickname,
FriendNickname,
FriendUnionId,
[]()
{
UE_LOG(LogTemp, Log, TEXT("Relationship synced"));
},
[](const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Sync failed: %s"), *Message);
});
展示 TapTap 用户名片
展示指定用户的名片弹窗,可用于关注或取消关注用户。
UTapRelationLite::ShowTapUserProfile(OpenId, UnionId);
国际化
TapTapRelationLite 支持设置语言:目前只支持简体中文