跳到主要内容
版本:v4

UE5 SDK 开发指南

本文介绍如何在游戏中加入好友系统。

集成前准备​

  1. 参考 TapTap 好友功能介绍确认选择好友(不含聊天)
  2. 参考 UE5 集成指南完成 TapSDK 基础接入
  3. 完成 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 支持设置语言:目前只支持简体中文