跳到主要内容

SDK配置

1. **导入各平台的package包

点击“Assets -> Import Package -> Custom Package”导入所有资源.

信息

资源包中的UIMain.cs是API demo 的脚本,直接挂载到Main Camera上,即可测试SDK API.(正式游戏发包时,可删除该脚本)

2.资源包内容简介

Plugins: 插件目录,包含Android、OpenHarmony、Switch、Steam、WeGame、MiniGame、PS4、XboxOne平台插件管理工具

Editor: iOS平台插件管理工具以及相关的文件配置等

script:脚本目录

  • DHSDKHelper.cs: SDK所有的接口都封装在这个里面 JsonUtils.cs: SDK和插件通信数据采用json数据格式

  • UIMain.cs: SDK调⽤的demo实例,可以作为参考API用法

3.Android配置

3.1

覆写启动Activity’s lifecyfle方法

(以默认Activity为例)

<activity>
android:name="com.dhplugin.unity.DHUnityActivity"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation
|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
android:screenOrientation="填写程序方向portrait(竖屏) or landscape(横屏) " >

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
<meta-data
android:name="unityplayer.ForwardNativeEventsToDalvik"
android:value="false" />

</activity>

信息

启动Activity可自定义, 但必须覆写Activity生命周期方法, Override方式如下:

    Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
DHUnityHelper.onCreate(this);
}
@Override
protected void onStart() {
super.onStart();
DHUnityHelper.onStart(this);
}
@Override
protected void onResume() {
super.onResume();
DHUnityHelper.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
DHUnityHelper.onPause(this);
}
@Override
protected void onStop() {
super.onStop();
DHUnityHelper.onStop(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
DHUnityHelper.onDestroy(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
DHUnityHelper.onActivityResult(this, requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}

信息

DHUnityHelper类在dh-unityplugin.jar中, 若游戏没有自身启动Activity, 可直接使用默认启动Activity

3.2 合并AndroidManifest配置

具体配置文件放在: /Assets/Plugins/Android/AndroidManifest.xml, 请按Android渠道参数说明.doc配置参数

4.iOS相关配置

4.1 iOS Sign in with Apple和Universal Link配置

信息

添加Sign in with Apple和Universal Link后,Apple后台的包名和证书也需要更新,否则会编译报错。

警告

Sign in with Apple功能接入需要XCode版本至少大于11才行,否则会报错。

在Xcode工程的Target->Signing&Capabilities中,点击+Capabilitity

添加Associated Domains模块

添加后,在里面填写Universal Link 地址参数:applinks:sdk-config.17m3.com

然后继续点击+Capability,选择Sign in with Apple选项

添加后最终效果如下

4.2 iOSManifest.projconfig配置

在Editor->Mods 下的iOSManifest.projconfig文件需要配置相关参数,可以文本格式打开.

里面有三个参数:"projmods","URLTypeSchemes","AppChannel","projmods":负责配置是使用苹果In-App Purchase还是使用越狱渠道支付;

"URLTypeSchemes":负责设置工程的URLScheme,用于第三方授权登录时回调,主要格式如下,dh+appID,tencent+QQKey,wx+ WeiXinKey,wb+ weiboKey, "dianhunxqtweixinalipay"是支付所需参数,不需要修改,这些key值请参照5.2参数说明;

"AppChannel":为1时会在unity导出的UnityAppController.mm文件插入sdk所需代码,默认为1不用修改;

示例如下(使用的是越狱渠道支付)

{
"projmods": ["DHUnitySDKMain","DHUnitySDKLogin","DHUnitySDKAliPay","DHUnitySDKDataCollection","DHUnitySDKShare","DHUnitySDKPush"],
"URLTypeSchemes": ["dh1297305671","dianhunxqtweixinalipay","tencent1103300313","wx932f7c792a64900f","wb1213431043"],
"AppChannel": 1
}

如果想要使用苹果In-App purchase支付,"projmods"参数改为如下

"projmods": ["DHUnitySDKMain","DHUnitySDKLogin","DHUnitySDKAppStorePay 
","DHUnitySDKDataCollection","DHUnitySDKShare","DHUnitySDKPush"]

4.3 IOSMainConfig.plist配置

在Editor->Mods->iOS->DHSDKMain目录下需要配置IOSMainConfig.plist文件里面游戏的相关参数,如下

参数类型含义是否必须
appIDString产品ID,SDK必要参数,由开放平台分配Y
loginIsShowTouristBoolean登录是否显示游客登录选项Y
loginMainChannelString登录主渠道号N
loginSecoChannelString登录次渠道号N
loginRegCodeString注册邀请码,支持注册功能,SDK服务器将分配给相应的产品注册邀请码Y
KDKeyString用于第三方调用的参数,该参数用于”口袋梦三国”授权登录N
QQKeyString应用在QQ互联注册并审核后的APP IDY
WeiXinKeyString应用在微信开放平台注册并审核后的APP IDY
WeiXinSecretString应用在微信开放平台注册的KEYY
weiboKeyString应用在新浪微博开放平台注册并审核后的APP KeyN
weiboRedirectUrlString应用在新浪微博开放平台注册并审核后的授权回调页 地址,在新浪微博开放平台高级信息中设置,如无特别 需求,推荐填新浪默认地址(https://api.weibo.com/oauth2/default.html\)N
versionString应用版本号Y
isPayTestBoolean是否选择测试支付Y
TalkingDataAppidString数据收集后台talkingData应用IDN
TalkingDataChannelString数据收集TalkingData渠道名称N
TalkingDataKeyString数据收集后台talkingdata应用的keyN
ADTrackingAppidString数据收集后台ADTracking应用IDN
ADTrackingChannelString数据收集ADTracking渠道名称N
ADTrackingKeyString数据收集后台ADTracking应用的keyN
UMKeyString国内友盟分享需要的Key,可去友盟后台申请N
XGAPPIDString信鸽推送后台申请的APPIDN
XGKeyString信鸽推送后台申请的APPKeyN
信息

QQkey,weiboKey,XGAPPID等参数需要去相关平台申请,可能会有延时

4.4 info.plist配置(如自动打包配置失败)

配置好了IOSMainConfig.plist后还需要对XCode工程的Info.plist文件进行配置,才能正确处理登录,分享授权等流程

4.5 iOS信鸽推送相关配置

需要在苹果后台开启应用包名的推送功能,并在XCode工程中进行如下配置

信鸽后台配置:

可以前往信鸽网站http://xg.qq.com/?ADTAG=EXTERNAL.MEDIA.PUSH_11 去创建信鸽推送后台应用,并获取推送的参数,填到IOSMainConfig.plist中的XGAPPID和XGKey中

信鸽后台参数示例

private constructor() { ... this.threadWorker.onmessage = (msg) => { ... if (msg.data.type == "RUN_ON_UI_THREAD_JS") { ... //添加如下代码 if (funcName == DHHarmonyManager.CALL_DHSDK) { let subFuncName:string = msg.data.subFuncName TuanjieLog.info('%{public}s', '引擎调用电魂sdk接口:' + subFuncName); let subFuncParams:string[] = msg.data.subFuncParams DHHarmonyManager.callSdkFunction(subFuncName, subFuncParams) } } } }

5. 鸿蒙配置

5.1、SDK说明

提示

SDK提供两种zip资源,一种是不包含配置的SDK,一种是包含配置的SDK。包含配置的SDK为正式参数,游戏直接替换配置文件或替换内部参数;不包含配置的SDK仅做接入使用,无法联调。

Java环境要求JDK17

5.1.1、SDK目录结构说明

  • /demo :demo工程

  • /resource : SDK资源

    /resource/entry/libs/dhsdkhelper.har : SDK har包

    /resource/entry/src/main/resources/rawfile/dh_config.json : SDK配置文件,直接拷贝至/entry/src/main/resources/rawfile目录

    /resource/entry/src/main/resources/rawfile/dh_wenxin_config.json : SDK配置文件,直接拷贝至/entry/src/main/resources/rawfile目录

    /resource/entry/build-profile.json5 : Module级配置文件

    /resource/entry/oh-package.json5 : Module级配置文件

    /resource/hvigor/hvigor-config.json5 : 编译工具版本配置文件

    /resource/material : 签名配置目录

    /resource/build-profile.json5 : 工程级构建配置文件

    /resource/metadata.json5 : SDK自定义的metadata配置

    /resource/oh-package.json5 : 工程级配置文件

    /resource/*-debug.p7b : 联调版本p7b profile

    /resource/*-publish.p7b : 发布版本p7b profile

    /resource/dh-debug.cer : 联调版本cer

    /resource/dh-release.cer : 发布版本cer

    /resource/dh.p12 : 签名文件

5.2 配置文件修改

提示

团结引擎1.3.0之前版本导出的工程为ts模式,且api为11,需要手动Export工程然后使用DevEco迁移api12后编译出包。团结引擎1.3.0及以后版本默认导出ets模式,api为12,不需要手动迁移。

5.2.1 工程级build-profile.json5

参考/resource/build-profile.json5,拷贝内部app/signingConfigs值替换游戏app/signingConfigs值
说明:name为default的配置是联调签名配置,name为publish的配置是发布签名配置,根据当前包体属性选择修改app/products元素中的signingConfig值
示例如下:
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"storePassword": "***",
"certpath": "dh-debug.cer",
"keyAlias": "***",
"keyPassword": "***",
"profile": "zhzf2-debug.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "dh.p12"
}
},
{
"name": "publish",
"type": "HarmonyOS",
"material": {
"storePassword": "***",
"certpath": "dh-release.cer",
"keyAlias": "***",
"keyPassword": "***",
"profile": "zhzf2-publish.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "dh.p12"
}
}],
"products": [
{
"name": "default",
"signingConfig": "default",
"compatibleSdkVersion": "5.0.0(12)",
"runtimeOS": "HarmonyOS"
}]
}

5.2.2 工程级oh-package.json5(团结引擎1.3.0及以上版本不需要操作)

直接拷贝平台/resource/oh-package.json5到项目根目录,不需要修改

5.2.3 entry/build-profile.json5

如果研发有动态import模块,请buildOption/arkOptions/runtimeOnly/packages的数组值中追加dhsdkhelper;
否则拷贝arkOptions属性到buildOption节点
示例如下:
"buildOption": {
"arkOptions": {
"runtimeOnly": {
// 配置本模块变量动态import其他模块名,要求与dependencies中配置的名字一致。
"packages": [
"dhsdkhelper"
]
}
}
}

5.2.4 entry/oh-package.json5

如果研发有引用模块,记得保留现有dhsdkhelper的引用,dependencies值中追加"dhsdkhelper": "file:libs/dhsdkhelper.har",同时执行ohpm install;
注意:追加内容不允许修改!!!
示例如下:
"dependencies": {
"dhsdkhelper": "file:libs/dhsdkhelper.har"
}

5.2.5 entry/src/main/module.json5

  • 请将/resource/metadata.json5的metadata数组内部元素合并追加到游戏工程entry/src/main/module.json5的module/metadata数组中
    注意:如果是更新sdk请先移除原电魂SDK中的metadata元素!!!

5.2.6 hvigor/hvigor-config.json5(团结引擎1.3.0及以上版本不需要操作)

直接拷贝平台/resource/hvigor/hvigor-config.json5,不需要修改

5.2.7 修改包名

修改根目录AppScope目录的app.json5文件,替换bundleName节点属性为游戏的正式包名

5.3 文件资源拷贝

5.3.1 签名文件

解压sdk资源包,拷贝/resource/material目录、/resource/*.p7b文件、/resource/*.cer文件、/resource/dh.p12 共一个目录,5个文件到游戏工程根目录下

5.3.2 har包

在entry目录下创建libs目录,解压sdk资源包,将resource/entry/libs目录下的dhsdkhelper.har拷贝至libs目录,文件名不可修改

5.3.3 rawfile

拷贝/resource/entry/src/main/resources/rawfile目录到游戏工程entry/src/main/resources目录下

5.4 代码处理

5.4.1 TuanjiePlayerAbility.ets

  • 添加引用
import { DHSDKHelper } from 'dhsdkhelper';
  • 调用生命周期方法

在onWindowStageCreate生命周期调用DHSDKHelper的onWindowStageCreate生命周期方法,示例如下:

onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
TuanjieLog.info('%{public}s', 'TuanjiePlayerAbility onWindowStageCreate');
DHSDKHelper.onWindowStageCreate(this.context,windowStage)
// set full screen at first
let windowClass = windowStage.getMainWindowSync();
try {
SetToGlobalThis(WindowUtils.MainWindowKey, windowClass);
WindowUtils.setWindowSizeChangeCallback();
WindowUtils.setWindowAvoidAreaChangeCallBack();
windowClass.setFullScreen(true, (err, data) => {
if (err.code) {
console.error('Failed to enable the full-screen mode. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data));
});
} catch (err) {
console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));
}

5.4.2 TuanjiePlayerAbilityIndex.ets

  • 添加引用

    import { DHSDKHelper } from 'dhsdkhelper';
    import { ADInfo, DHCallbackRequestCode, DHCallbackResultCode, DHHarmonyManager } from '../DHHarmonyManager';
提示

收到sdk同意温馨提示回调后游戏才可以收集用户信息

  • 设置接口调用监听

    在TuanjiePlayer的aboutToAppear生命周期中添加如下代码:

    aboutToAppear(): void {
    SetToGlobalThis('launchContext', getContext(this));
    TuanjieLog.info('%{public}s', '引擎aboutToAppear');
    DHHarmonyManager.getInstance().setListener((funcName, funcParams) => {
    TuanjieLog.info('%{public}s', '引擎监听到sdk接口调用:' + funcName);
    //主线程调用SDK接口
    if (funcName == DHHarmonyManager.FUNCTION_INIT) {
    DHSDKHelper.init(getContext(this), (requestCode: number, resultCode: number, data: string) => {
    TuanjieLog.info('%{public}s', '引擎监听到回调:' + requestCode + ',' + resultCode + ',' + data);
    //判断同意温馨提示成功,成功后才游戏才可以收集用户信息
    if (requestCode == -1 && resultCode == 0) {

    }
    TuanjieMainWorker.getInstance()
    .postMessage({
    type: 'callbackToUnity',
    requestCode: requestCode,
    resultCode: resultCode,
    data: data
    })
    })
    } else if (funcName == DHHarmonyManager.FUNCTION_LOGIN) {
    DHSDKHelper.login(getContext(this))
    } else if (funcName == DHHarmonyManager.FUNCTION_PAY) {
    if (funcParams.length > 0) {
    DHSDKHelper.pay(getContext(this), funcParams[0])
    }
    } else if (funcName == DHHarmonyManager.FUNCTION_SHOW_FAQS) {
    if (funcParams.length > 0) {
    DHSDKHelper.showFaqs(getContext(this), funcParams[0])
    }
    } else if (funcName == DHHarmonyManager.FUNCTION_SET_ALIAS) {
    if (funcParams.length > 0) {
    DHSDKHelper.setAlias(getContext(this), funcParams[0])
    }
    } else if (funcName == DHHarmonyManager.FUNCTION_DEL_ALIAS) {
    if (funcParams.length > 0) {
    DHSDKHelper.delAlias(getContext(this), funcParams[0])
    }
    } else if (funcName == DHHarmonyManager.FUNCTION_OPEN_USER_CENTER) {
    if (funcParams.length > 0) {
    DHSDKHelper.openUserCenter(getContext(this), funcParams[0])
    }
    } else if (funcName == DHHarmonyManager.FUNCTION_QUERY) {
    if (funcParams.length > 0) {
    DHSDKHelper.query(getContext(this), funcParams[0])
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_EXEC) {
    if (funcParams.length > 0) {
    DHSDKHelper.exec(getContext(this), funcParams[0])
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_SHARE_PHOTO) {
    if (funcParams.length > 0) {
    DHSDKHelper.sharePhoto(getContext(this), funcParams[0])
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_SHARE_LINKS) {
    if (funcParams.length > 0) {
    DHSDKHelper.shareLinks(getContext(this), funcParams[0])
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_COULD_PLAY_AD) {
    if (funcParams.length > 0) {
    try{
    let adInfo:ADInfo = JSON.parse( funcParams[0])
    DHSDKHelper.couldPlayAd(getContext(this), adInfo.uid,adInfo.adType)
    }catch(e){
    TuanjieLog.error('%{public}s', '引擎异常:'+funcParams[0]+','+e);
    }
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_PLAY_AD) {
    if (funcParams.length > 0) {
    try{
    let adInfo:ADInfo = JSON.parse( funcParams[0])
    DHSDKHelper.playAd(getContext(this), adInfo.uid,adInfo.adType)
    }catch(e){
    TuanjieLog.error('%{public}s', '引擎异常:'+funcParams[0]+','+e);
    }
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_SET_GAME_USER_INFO) {
    if (funcParams.length > 1) {
    DHSDKHelper.setGameUserInfo(getContext(this), funcParams[0],funcParams[1])
    }
    }else if (funcName == DHHarmonyManager.FUNCTION_TRACK) {
    if (funcParams.length > 1) {
    DHSDKHelper.trackEvent(getContext(this), funcParams[0],funcParams[1])
    }
    }
    })
    }

    5.4.3 TuanjieMainWorker.ets

  • 添加引用

    import { DHHarmonyManager } from '../DHHarmonyManager';

    在constructor构造方法中定义的onmessage类型别名中,msg.data.type为"RUN_ON_UI_THREAD_JS"的逻辑代码中添加funcName判断,建议在最后添加如下代码

    private constructor() {
    ...
    this.threadWorker.onmessage = (msg) => {
    ...
    if (msg.data.type == "RUN_ON_UI_THREAD_JS") {
    ...
    //添加如下代码
    if (funcName == DHHarmonyManager.CALL_DHSDK) {
    let subFuncName:string = msg.data.subFuncName
    TuanjieLog.info('%{public}s', '引擎调用电魂sdk接口:' + subFuncName);
    let subFuncParams:string[] = msg.data.subFuncParams
    DHHarmonyManager.callSdkFunction(subFuncName, subFuncParams)
    }
    }
    }
    }