快速接入
Unity SDK 接入指南
本文档为Unity接入 引力引擎的技术接入方案,具体 Demo 请参考GitHub开源项目,Demo 工程中可以参考 GravityEngineDemo.cs
脚本中对每一个方法的调用示例。
提示
在接入前, 请先阅读 接入前准备
注意
在正式上线之前,请参考 接入验证 完成接入校验。
1. SDK 基础配置
1.1 SDK 引入
下载最新的 GravityEngine.unitypackage 资源文件,并导入资源文件到您的项目中:Assets > Import Package > Custom Package
,选中您刚刚下载的文件。
注意
- 微信小游戏:需要先接入微信团队开源的 Unity 转微信小游戏的插件。
- 抖音小游戏:需要先接入头条提供的 StarkSDK 插件。
- 快手小游戏:需要先接入快手提供的 SDK 插件 详情参考。
1.2 添加全局宏参数
正式接入之前,您需要针对不同的平台添加不同的全局宏参数。
- 微信小游戏:
GRAVITY_WECHAT_GAME_MODE
- 抖音小游戏:
GRAVITY_BYTEDANCE_GAME_MODE
- 抖音小游戏 TT SDK 模式:
GRAVITY_BYTEDANCE_TT_GAME_MODE
如您已升级到 TT SDK,使用本模式,详情请参考抖小 SDK 官方文档 - 快手小游戏:
GRAVITY_KUAISHOU_GAME_MODE
- 快手小游戏 WEBGL:
GRAVITY_KUAISHOU_WEBGL_GAME_MODE
- 支付宝小游戏:
GRAVITY_ALIPAY_GAME_MODE
- Android、iOS:不需要额外配置宏参
添加步骤如下:
- 打开 Project Settings 界面;
- 找到
Scripting Define Symbols
,新增一行输入对应平台的全局宏参数,然后点击 Apply 按钮完成设置
注意
请确保正式打包上线时,选中的宏参数依然正常生效,否则会影响到对应平台的事件上报,影响买量效果!
1.3 配置并启动 SDK
请参考以下代码来进行 SDK 的初始化,建议在能够获取到用户唯一 ID,如微信小游戏、抖音小游戏、快手小游戏的openId
、Android 设备的oaid
、iOS 设备的IDFV
时,尽早的进行初始化。
// 手动初始化(动态挂载 GravityEngineAPI 脚本)
new GameObject("GravityEngine", typeof(GravityEngineAPI));
//设置实例参数并启动引擎,将以下三个参数修改成您应用对应的参数,参数可以在引力后台--设置--应用管理中查看
string accessToken = "your_access_token"; // 项目通行证,在:网站后台-->设置-->应用列表中找到Access Token列 复制(首次使用可能需要先新增应用)
string clientId = "your_user_id"; // 通常是某一个用户的唯一标识,如产品为小游戏,则必须填用户的的 openId
// 启动引力引擎
GravityEngineAPI.StartGravityEngine(accessToken, clientId, GravityEngineAPI.SDKRunMode.NORMAL);
// 手动初始化(动态挂载 GravityEngineAPI 脚本)
new GameObject("GravityEngine", typeof(GravityEngineAPI));
//设置实例参数并启动引擎,将以下三个参数修改成您应用对应的参数,参数可以在引力后台--设置--应用管理中查看
string accessToken = "your_access_token"; // 项目通行证,在:网站后台-->设置-->应用列表中找到Access Token列 复制(首次使用可能需要先新增应用)
string clientId = "your_user_id"; // 通常是某一个用户的唯一标识,如产品为小游戏,则必须填用户的的 openId
// 启动引力引擎
GravityEngineAPI.StartGravityEngine(accessToken, clientId, GravityEngineAPI.SDKRunMode.NORMAL);
// 手动初始化(动态挂载 GravityEngineAPI 脚本)
new GameObject("GravityEngine", typeof(GravityEngineAPI));
//设置实例参数并启动引擎,将以下三个参数修改成您应用对应的参数,参数可以在引力后台--设置--应用管理中查看
string accessToken = "your_access_token"; // 项目通行证,在:网站后台-->设置-->应用列表中找到Access Token列 复制(首次使用可能需要先新增应用)
string clientId = "your_user_id"; // 通常是某一个用户的唯一标识,如产品为小游戏,则必须填用户的的 openId
// 启动引力引擎
GravityEngineAPI.StartGravityEngine(accessToken, clientId, GravityEngineAPI.SDKRunMode.NORMAL);
// 手动初始化(动态挂载 GravityEngineAPI 脚本)
new GameObject("GravityEngine", typeof(GravityEngineAPI));
// Android原生应用示例
//设置实例参数并启动引擎,将以下三个参数修改成您应用对应的参数,参数可以在引力后台--设置--应用管理中查看
string accessToken = "your_access_token"; // 项目通行证,在:网站后台-->设置-->应用列表中找到Access Token列 复制(首次使用可能需要先新增应用)
string clientId = "your_user_id"; // 通常是某一个用户的唯一标识
string channel = "xiaomi"; // 安装包渠道来源,比如xiaomi、huawei、应用宝
// 启动引力引擎
GravityEngineAPI.StartGravityEngine(accessToken, clientId, GravityEngineAPI.SDKRunMode.NORMAL, channel);
// 原生app开启自动采集,并设置自定属性
GravityEngineAPI.EnableAutoTrack(AUTO_TRACK_EVENTS.APP_ALL, new Dictionary<string, object>()
{
{"auto_track_key", "auto_track_value"} // 静态属性
});
// 手动初始化(动态挂载 GravityEngineAPI 脚本)
new GameObject("GravityEngine", typeof(GravityEngineAPI));
// iOS原生应用示例
//设置实例参数并启动引擎,将以下参数修改成您应用对应的参数,参数可以在引力后台--设置--应用管理中查看
string accessToken = "your_access_token";
string clientId = "default_placeholder"; // iOS产品传固定值default_placeholder,使用SDK提供的默认值即可,SDK会自动采集client ID
// 启动引力引擎
GravityEngineAPI.StartGravityEngine(accessToken, clientId, GravityEngineAPI.SDKRunMode.NORMAL, "appstore");
// 原生app开启自动采集,并设置自定属性
GravityEngineAPI.EnableAutoTrack(AUTO_TRACK_EVENTS.APP_ALL, new Dictionary<string, object>()
{
{"auto_track_key", "auto_track_value"} // 静态属性
});
注意
- 如果您的项目为微信小游戏或者抖音小游戏,您需要将
https://backend.gravity-engine.com
配置到后台 request 合法域名列表中。
1.4 初始化
在可以获取到用户唯一性信息时调用本方法,推荐首次安装启动时调用,其他方法均需在本方法回调成功之后才可正常使用。
iOS 产品比较特殊,需要在用户同意隐私协议弹窗并向用户展示过 App Tracking Transparency(ATT)许可弹窗 弹窗之后,无论用户是否允许 ATT 追踪,都要执行引力的初始化逻辑,具体请参考 iOS SDK 接入指南。
public class InitializeCallbackImpl : IInitializeCallback
{
// 初始化失败之后回调,errorMsg为报错信息
public void onFailed(string errorMsg)
{
Debug.Log("initialize failed with message " + errorMsg);
}
// 初始化成功之后回调
public void onSuccess()
{
Debug.Log("initialize success");
Debug.Log("initialize call end");
// 建议在此执行一次Flush
GravityEngineAPI.Flush();
}
}
/// <summary>
/// 在引力引擎初始化,其他方法均需在本方法回调成功之后才可正常使用
/// </summary>
/// <param name="clientId"></param> 用户唯一标识,如产品为小游戏,则必须填用户openid(如传空,则使用调用StartGravityEngine时传入的clientID;如传,则会使用当前传入的clientID)
/// <param name="nickname"></param> 用户昵称
/// <param name="version"></param> 用户注册的程序版本,比如当前小游戏的版本号
/// <param name="openId"></param> open id (小程序/小游戏必填)
/// <param name="enableSyncAttribution"></param> 是否开启同步获取归因信息,具体请参考同步归因:https://doc.gravity-engine.com/turbo-integrated/sync_attribution.html
/// <param name="initializeCallback"></param> 网络回调,其他方法均需在回调成功之后才可正常使用
/// <exception cref="ArgumentException"></exception>
GravityEngineAPI.Initialize("your_user_client_id", "name_123", 1, "your_openid_111", false, new InitializeCallbackImpl());
public class InitializeCallbackImpl : IInitializeCallback
{
// 初始化失败之后回调,errorMsg为报错信息
public void onFailed(string errorMsg)
{
Debug.Log("initialize failed with message " + errorMsg);
}
// 初始化成功之后回调
public void onSuccess()
{
Debug.Log("initialize success");
Debug.Log("initialize call end");
// 建议在此执行一次Flush
GravityEngineAPI.Flush();
}
}
/// <summary>
/// 在引力引擎注册,其他方法均需在本方法回调成功之后才可正常使用(iOS专用)
/// </summary>
/// <param name="enableAsa"></param> 是否开启asa归因
/// <param name="caid1MD5"></param> 当前用户中广协 ID 的 md5 hash(20230330 版本)(可为空)
/// <param name="caid2MD5"></param> 当前用户中广协 ID 的 md5 hash(20220111 版本)(可为空)
/// <param name="enableSyncAttribution"></param> 是否开启同步获取归因信息,具体请参考同步归因:https://doc.gravity-engine.com/turbo-integrated/sync_attribution.html
/// <param name="initializeCallback"></param> 网络回调,其他方法均需在回调成功之后才可正常使用
/// <exception cref="ArgumentException"></exception>
GravityEngineAPI.InitializeIOS(false, caid1Md5, caid2Md5, false, new InitializeCallbackImpl());
注意
openId
:微信和抖音、快手小游戏此参数为必填项,是买量归因必须的参数,请注意一定传入!- 首次调用后,需要等
IInitializeCallback
的onSuccess
回调之后才能继续调用其他事件上报的方法,否则会上报失败! - 用户整个生命周期内,初始化接口只需要调用一次,调用成功之后,后续冷启动可以不再调用,只需要保证 SDK 正确执行初始化逻辑即可(多次调用也不会有问题,引力做了兼容)。
2. 行为事件上报
通过 GravityEngineAPI.Track()
可以上报事件及其属性。一般情况下,您可能需要上传十几到上百个不同的事件,如果您是第一次使用引力引擎事件采集系统,我们推荐您先上传几个关键事件。
我们也支持了若干自动采集事件,包括游戏启动、关闭、异常、小游戏添加收藏、Unity 场景加载或者卸载等事件,您可以根据业务需求选择是否开启自动采集事件。
2.1 自定义事件上报
建议您先在元事件中添加自定义事件,然后在游戏中指定位置埋点调用 Track
方法上报自定义事件。
Dictionary<string, object> properties = new Dictionary<string, object>();
properties["channel"] = "base";//字符串,长度不超过2048
properties["age"] = 1;//数字
properties["isVip"] = true;//布尔
properties["birthday"] = DateTime.Now;//时间
properties["movies"] = new List<string>() { "Interstellar", "The Negro Motorist Green Book" };//字符串元素的数组 最大元素个数为 500
GravityEngineAPI.Track("TEST_EVENT_NAME",properties);
- 事件名称是
string
类型,只能以字母开头,可包含数字,字母和下划线 “_”,长度最大为 50 个字符。 - 事件属性是
Dictionary<string, object>
类型,其中每个元素代表一个属性;- 事件属性
Key
为属性名称,为string
类型,规定只能以字母开头,包含数字,字母和下划线 “_”,长度最大为 50 个字符; - 属性
Value
支持string
、int
、float
、bool
、DateTime
、List<string>
;
- 事件属性
当您调用 Track()
时,SDK 会取系统当前时间作为事件发生的时刻,如果您需要指定事件时间,可以传入 DateTime 类型的参数来设置事件触发时间。
SDK 提供了时间校准接口,允许使用服务器时间对 SDK 时间进行校准,具体请参考 Demo 中对 CalibrateTime
和 CalibrateTimeWithNtp
方法的使用。
注意
尽管事件可以设置触发时间,但是接收端会做如下的限制:只接收相对服务器时间在前 10 天至后 1 小时的数据,超过时限的数据将会被视为异常数据,整条数据无法入库!
2.2 业务注册事件上报(可选)
GravityEngineAPI.TrackMPRegister();
GravityEngineAPI.TrackAppRegister();
2.3 付费事件上报
当用户发生付费行为时,需要调用 TrackPayEvent
方法记录用户付费事件,此事件非常重要,会影响买量和 ROI 统计,请务必重点测试
/// <summary>
/// 上报付费事件 PayEvent
/// </summary>
/// <param name="payAmount"></param> 付费金额 单位为分
/// <param name="payType"></param> 货币类型 按照国际标准组织ISO 4217中规范的3位字母,例如CNY人民币、USD美金等
/// <param name="orderId"></param> 订单号
/// <param name="payReason"></param> 付费原因 例如:购买钻石、办理月卡
/// <param name="payMethod"></param> 付费方式 例如:支付宝、微信、银联等
GravityEngineAPI.TrackPayEvent(300, "CNY", "your_order_id", "月卡", "支付宝");
相关信息
如果您需要通过后端 API 方式上报付费事件,请参考 混合上报模式 来接入事件上报接口报送付费事件。
警告
- 参数
payAmount
单位为分,请务必注意,传错单位可能会导致买量受到影响! - 引力引擎会通过订单号
orderId
去重,避免重复上报,请务必传入!
2.4 广告观看事件上报
若您的产品内有广告变现,则需要在用户点击广告观看的同时上报用户广告观看事件给引力,具体参考如下:
/// <summary>
/// 上报微信小游戏广告观看事件 AdShow
/// </summary>
/// <param name="adType"></param> 广告类型 取值为:reward、banner、native、interstitial、video_feed、video_begin,分别对应:激励视频广告、Banner广告、原生模板广告、插屏广告、视频广告、视频贴片广告
/// <param name="adUnitId"></param> 广告位ID(一般以adunit开头,注意不要填错,会导致广告收入统计不准!)
/// <param name="otherProperties"></param> 其他需要携带的自定义参数
var otherProperties = new Dictionary<string, object>()
{
{"other_key", "other_value"}
};
GravityEngineAPI.TrackWechatAdShowEvent("reward", "your_ad_unit_id", otherProperties);
/// <summary>
/// 上报原生App广告观看事件 AdShow
/// </summary>
/// <param name="adUnionType"></param> 广告聚合平台类型 (取值为:topon、gromore、admore、self,分别对应Topon、Gromore、Admore、自建聚合)
/// <param name="adPlacementId"></param> 广告瀑布流ID(广告位ID)
/// <param name="adSourceId"></param> 广告源ID(代码位ID)
/// <param name="adType"></param> 广告类型 (取值为:reward、banner、 native 、interstitial、 splash ,分别对应激励视频广告、横幅广告、信息流广告、插屏广告、开屏广告)
/// <param name="adnType"></param> 广告平台类型(取值为:csj、gdt、ks、 mint 、baidu,分别对应为穿山甲、优量汇、快手联盟、Mintegral、百度联盟)
/// <param name="ecpm"></param> 预估ECPM价格(单位为元)
GravityEngineAPI.TrackNativeAppAdShowEvent("topon", "placement_id", "ad_source_id", "reward", "csj", 1);
警告
- 微信小游戏需要参照 微信广告变现实时统计 一文,检查是否正确配置微信
access_token
,配置错误将无法正确获取广告变现数据! - 仅微信小游戏、小程序、Android、iOS 需要接入,抖音小游戏不要接入!抖音小游戏会由引力后端自动拉取。
2.5 设置事件公共属性
对于一些重要的属性,譬如玩家的区服和渠道等,这些属性需要设置在每个事件中,此时您可以将这些属性设置为公共事件属性。公共事件属性指的就是每个事件都会带有的属性,您可以调用 SetSuperProperties
来设置公共事件属性,我们推荐您在发送事件前,先设置公共事件属性。
Dictionary<string, object> superProperties = new Dictionary<string, object>()
{
{"SERVER", 0},
{"CHANNEL", "A3"}
};
GravityEngineAPI.SetSuperProperties(superProperties);
公共事件属性将会被保存到缓存中,无需每次启动 APP 时调用。如果调用 SetSuperProperties
上传了先前已设置过的公共事件属性,则会覆盖之前的属性。如果公共事件属性和 Track()
上传的某个属性的 Key 重复,则该事件的属性会覆盖公共事件属性。
- 如果您需要删除某个公共事件属性,可以调用
UnsetSuperProperty
清除其中一个公共事件属性; - 如果您想要清空所有公共事件属性,则可以调用
ClearSuperProperties
; - 如果您想要获取所有公共事件属性,可以调用
GetSuperProperties
;
// 清除属性名为 CHANNEL 的公共属性
GravityEngineAPI.UnsetSuperProperty("CHANNEL");
// 清空所有公共属性
GravityEngineAPI.ClearSuperProperties();
// 获取所有公共属性
GravityEngineAPI.GetSuperProperties();
注意
公共属性需要先在事件属性中添加,否则会上报失败!
2.6 记录事件时长
如果您需要记录某个事件持续时长,您可以调用 TimeEvent()
来开始计时,配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 $event_duration
这一属性来表示记录的时长,单位为秒。
// 调用 TimeEvent 开启对 TIME_EVENT 事件的计时
GravityEngineAPI.TimeEvent("TIME_EVENT");
// do some thing...
// 通过 Track 上传 TIME_EVENT 事件时,会在属性中添加 $event_duration 属性
GravityEngineAPI.Track("TIME_EVENT");
2.7 立即上报事件
如果需要立即上报缓存的事件,可以调用 Flush()
来上报所有缓存的事件。
// 调用 Flush() 上报缓存事件
GravityEngineAPI.Flush();
3. 用户属性上报
目前支持的用户属性设置接口为 UserSet
、UserSetOnce
、UserAdd
、UserUnset
、UserDelete
、UserAppend
.
3.1 设置用户属性
对于一般的用户属性,您可以调用 UserSet
来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性。
GravityEngineAPI.UserSet(new Dictionary<string, object>()
{
{"USER_PROP_NUM", 0},
{"USER_PROP_STRING", "A3"}
});
3.2 初始化用户属性
如果您要上传的用户属性只要设置一次,则可以调用 UserSetOnce
来进行设置,当该属性之前已经有值的时候,将会忽略这条信息:
GravityEngineAPI.UserSetOnce(new Dictionary<string, object>()
{
{"USER_PROP_NUM", -50},
{"USER_PROP_STRING", "A3"}
});
3.3 累加用户属性
当您要上传数值型的属性时,您可以调用 UserAdd
来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作。
GravityEngineAPI.UserAdd(new Dictionary<string, object>()
{
{"USER_PROP_NUM", -100.9},
{"USER_PROP_NUM2", 10.0}
});
设置的属性 key 为字符串,Value 只允许为数值。
3.4 重置用户属性
如果您需要重置用户的某个属性,可以调用 UserUnset
将该用户指定用户属性的值重置,此接口支持传入字符串、列表、布尔类型的参数:
// 删除单个用户属性
GravityEngineAPI.UserUnset("userPropertyName");
// 删除多个用户属性
GravityEngineAPI.UserUnset(new List<string>() {"age", "$name", "$first_visit_time", "movies"});
UserUnset: 的传入值为被重置属性的 Key 值。
3.5 清空用户属性
如果您要删除某个用户,可以调用 UserDelete
将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到。
GravityEngineAPI.UserDelete();
3.6 Array 属性追加
可以调用 UserAppend 为 List 类型的用户属性追加元素:
List<string> propList = new List<string>();
propList.Add("Interstellar");
propList.Add("The Negro Motorist Green Book");
// 为属性名为 movies 的用户属性追加 2 个元素
GravityEngineAPI.UserAppend(new Dictionary<string, object>()
{
{"movies", propList}
});
3.7 Array 属性去重追加
可以调用 UserUniqAppend 为 List 类型的用户属性进行去重追加元素:
List<string> propList = new List<string>();
propList.Add("Interstellar");
propList.Add("The Shawshank Redemption");
// 为属性名为 movies 的用户属性去重追加 2 个元素
GravityEngineAPI.UserUniqAppend(new Dictionary<string, object>()
{
{"movies", propList}
});
3.8 用户属性取最大值
可以调用 UserNumberMax
用来比较数值大小,保存较大的,如果没有这个 key,则新增 key,value 取本次的值
GravityEngineAPI.UserNumberMax("age", 10);
3.9 用户属性取最小值
可以调用 UserNumberMin
用来比较数值大小,保存较小的,如果没有这个 key,则新增 key,value 取本次的值
GravityEngineAPI.UserNumberMin("age", 10);
4. 其他功能
4.1 自动采集事件
引力引擎 SDK 支持自动采集一些基础事件以降低您的接入成本,您可以参考自动采集一文来快速开启。
4.2 开启 Debug 模式
SDK 支持在两种模式下运行:
- NORMAL: 普通模式,数据会存入缓存,并依据一定的缓存策略上报
- DEBUG: 测试模式,数据逐条上报。当出现问题时会以日志和异常的方式提示用户,也可以去
引力网站后台--设置--元数据--事件流
中查看实时上报的数据,辅助您判断数据接入是否正常。
您在调用 StartGravityEngine
初始化引擎时,可以传入 SDKRunMode
参数来指定 SDK 运行模式。
警告
Debug 模式仅仅用于集成阶段数据校验,不要在生产模式下使用!
4.3 校准时间
SDK 默认会使用本机时间作为事件发生时间上报,如果用户手动修改设备时间会影响到您的业务分析,您可以使用从服务端获取的当前时间戳对 SDK 的时间进行校准。此后,所有未指定时间的调用,包括事件数据和用户属性设置操作,都会使用校准后的时间作为发生时间。
//时间戳,单位毫秒 对应时间为1668982523000 2022-11-21 06:15:23
GravityEngineAPI.CalibrateTime(1668982523000);
我们也提供了从 NTP 获取时间对 SDK 校准的功能。您需要传入您的用户可以访问的 NTP 服务器地址。之后 SDK 会尝试从传入的 NTP 服务地址中获取当前时间,并对 SDK 时间进行校准。如果在默认的超时时间(3 秒)之内,未获取正确的返回结果,后续将使用本地时间上报数据。
//NTP 时间服务器校准,如:time.apple.com
GravityEngineAPI.CalibrateTimeWithNtp("time.apple.com");
提示
- 您需要谨慎地选择您的 NTP 服务器地址,以保证网络状况良好的情况下,用户设备可以很快的获取到服务器时间。
- 使用 NTP 服务进行时间校准存在一定的不确定性,建议您优先考虑用时间戳校准的方式。
除了以上校准时间接口外,SDK 还提供了所有用户属性接口的时间函数重载,您可以在调用用户属性相关接口时,传入 DateTime
对象,则系统会使用传入的 DateTime
对象来设定数据的 time
字段。
4.4 绑定三方平台
引力支持与其他三方的数据分析平台打通,具体调用如下:
4.4.1 数数
GravityEngineAPI.BindTAThirdPlatform(CURRENT_USER_TA_ACCOUNT_ID, CURRENT_USER_TA_DISTINCT_ID);
参数说明:
CURRENT_USER_TA_ACCOUNT_ID
:当前用户的数数账户 ID (#account_id)CURRENT_USER_TA_DISTINCT_ID
:当前用户的数数访客 ID (#distinct_id)
提示
引力会自动将引力 client ID
和您传入的数数 account_id
以及 distinct_id
做关联,在回调数数接口时,通过这个关联传递对应的 account_id
、distinct_id
给数数后台