内容概述

中国Unity封装了基于华为HMS/AGC服务的SDK,对于移动端项目开发,可以直接在Unity工程中集成使用各种华为功能,所构建出的安卓包可以使用户直接调用各种华为服务,以此打造高品质应用与体验。希望其效率与便捷性将能使开发工作变得更轻松!

SDK下载地址:

SDK功能涵盖:

目前Unity程序包中各服务对应的类、函数名称、以及用法均与华为保持一致,目前阶段所涵盖的华为服务具体包括:
1. 华为HMS:
    
    
App服务类(Ads广告变现、Analytics分析、GameService游戏服务、Location定位、Push推送)
2. 华为AGC:
    
    
开发类(AuthServices认证、CloudFunctions云函数、CloudDB云数据库、CloudStorage云存储) 质量类(Crash崩溃服务、APM性能管理) 增长类(RemoteConfiguration远程配置、AppLinking应用链接、AppMessaging应用内消息)

三步集成SDK:

使用方法为下载程序包并导入到Unity项目中进行开发。由于存在的差异,在开发过程中仍然需要进行简单的配置与代码添加,以最终完成对具体服务的集成。以下以实现对华为广告流量变现服务(Ads)的集成为例,分为三部分进行介绍,分别是:
一,华为账号设置 二,Unity项目设置 三,SDK集成开发

一,华为账号设置

首先需要为集成华为服务进行所需的账号服务的开通与配置。
  1. 开发者联盟账号注册及实名认证
  2. 开通商户服务
  3. 创建应用
  4. 开通API服务
  5. 签署《华为Ads 媒体服务协议》
  6. 添加媒体
  7. 添加广告位并获取广告ID

1,开发者联盟账号注册及实名认证

登录 华为开发者联盟 ,创建华为开发者账号,以及完成实名认证。参考华为文档: https://developer.huawei.com/consumer/cn/doc/distribution/monetize/registration-0000001061752683

2,开通商户服务

填写信息并开通华为商户服务。参考华为文档: https://developer.huawei.com/consumer/cn/doc/start/merchant-service-0000001053025967

3,创建应用

登录 华为开发者联盟 ,点击"管理中心",在AppGallery Connect控制台页面上创建项目,以及创建应用。创建成功后,自动跳转到对应的应用信息页面,在此页面你可以看到系统分发给此应用的APP ID和SecretKey等信息。

4,开通API服务

在项目的应用信息页面,选择API管理页签,根据实际需要选择打开对应API服务。

5,签署《华为Ads 媒体服务协议》

需要注意境内或境外身份开发主体对于使用广告服务的区别与限制!

6,添加媒体

登录 华为流量变现服务平台 ,在创建的应用添加媒体

7,添加广告位并获取广告ID

目前Unity华为服务SDK中支持的广告形式为“Rewarded Ads激励式广告”和“Interstitial插播式广告”两种,请根据对华为广告位形式的需求添加广告位。并获得广告位ID。
至此,成功获取上述广告位ID。请注意:此正式广告ID将用于后续的SDK集成开发中。
以上Unity所整理的华为步骤,也可以直接到华为开发者社区参考华为文档: https://developer.huawei.com/consumer/cn/doc/distribution/monetize/process-0000001062698798

二,Unity项目设置

为你的Unity项目设置构建环境,并为华为 SDK配置仓库及依赖包。
  1. 创建模版
  2. 设置模版
  3. 生成签名证书
  4. 生成签名证书指纹
  5. 回到华为添加指纹证书
  6. 下载并添加Agconnect-services.json 到Unity项目
  7. 设置构建包名,及其他设置

1,创建模版

首先,确保你的Unity项目构建平台切换为安卓平台:
Editor -> Build Settings -> Platform -> Andriod -> Switch Platform//切换到安卓平台
    
    
可选项:这个时候也可以选择连上你的华为手机进行调试(手机打开开发者模式,以及USB调试)Run device -- > 选择测试设备

2,设置模版

其次,完成以下构建环境的设置:
Edit -> Project Settings -> Player -> Android(icon) -> Publishing Settings -> Build -> 勾选以下环境配置项目:
  1. Custom Main Manifest --> AndriodManifest.xml
  2. Custom Launcher Manifest --> LauncherManifest.xml
  3. Custom Main Gradle Template --> mainTemplate.gradle
  4. Custom Launcher Gradle Template --> launcherTemplate.gradle
  5. Custom Base Grade Template --> baseProjectTemplate.gradle
在Publishing Setting中勾选后,这些文件将自动出现在Unity项目文件夹中,项目文件夹路径为:
Project -> Assets -> Plugins -> Android ->
分别找到这些文件,并对它们进行以下代码修改配置:
1, AndroidManifest.xml
    
    
< ? xml version = "1.0" encoding = "utf-8" ? > < ! -- GENERATED BY UNITY . REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN -- > < manifest xmlns : android = "http://schemas.android.com/apk/res/android" package = "com.unity3d.player" xmlns : tools = "http://schemas.android.com/tools" > < application > < activity android : name = "com.unity3d.player.UnityPlayerActivity" android : theme = "@style/UnityThemeSelector" > < 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" / > < / activity > < / application > < / manifest >
P.S. 调用Push 和Location SDK请 参考文档 添加其他代码
2, LauncherManifest.xml
    
    
< ? xml version = "1.0" encoding = "utf-8" ? > < ! -- GENERATED BY UNITY . REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN -- > < manifest xmlns : android = "http://schemas.android.com/apk/res/android" package = "com.unity3d.player" xmlns : tools = "http://schemas.android.com/tools" android : installLocation = "preferExternal" > < supports - screens android : smallScreens = "true" android : normalScreens = "true" android : largeScreens = "true" android : xlargeScreens = "true" android : anyDensity = "true" / > < application android : extractNativeLibs = "true" android : label = "@string/app_name" android : icon = "@mipmap/app_icon" / > < / manifest >
3,mainTemplete.gradle
    
    
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN apply plugin : 'com . android . library' * * APPLY_PLUGINS * * dependencies { implementation fileTree ( dir : 'libs' , include : [ ' * . jar' ] ) implementation 'com . huawei . hms : hianalytics : 5.0 .0 .301 ' implementation 'com . huawei . agconnect : agconnect - core : 1.2 .0 .300 ' implementation 'com . huawei . hms : base : 4.0 .1 .300 ' implementation 'com . huawei . hms : hwid : 4.0 .1 .300 ' implementation 'com . huawei . hms : game : 4.0 .1 .300 ' * * DEPS * * } android { compileSdkVersion * * APIVERSION * * buildToolsVersion ' * * BUILDTOOLS * * ' compileOptions { sourceCompatibility JavaVersion . VERSION_1_8 targetCompatibility JavaVersion . VERSION_1_8 } defaultConfig { minSdkVersion * * MINSDKVERSION * * targetSdkVersion * * TARGETSDKVERSION * * ndk { abiFilters * * ABIFILTERS * * } versionCode * * VERSIONCODE * * versionName ' * * VERSIONNAME * * ' consumerProguardFiles 'proguard - unity . txt' * * USER_PROGUARD * * } lintOptions { abortOnError false } aaptOptions { noCompress = [ ' . ress' , ' . resource' , ' . obb' ] + unityStreamingAssets . tokenize ( ' , ' ) ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" } * * PACKAGING_OPTIONS * * } * * REPOSITORIES * * * * IL_CPP_BUILD_SETUP * * * * SOURCE_BUILD_SETUP * * * * EXTERNAL_SOURCES * *
4,launcherTemplate.gradle
    
    
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN apply plugin : 'com . android . application' dependencies { implementation project ( ' : unityLibrary' ) implementation 'com . huawei . hms : ads - lite : 13.4 .29 .303 ' implementation 'com . huawei . hms : ads - consent : 3.4 .30 .301 ' implementation 'com . huawei . hms : push : 4.0 .3 .301 ' implementation 'com . huawei . hms : hianalytics : 5.1 .0 .300 ' implementation 'com . android . support : appcompat - v7 : 28.0 .0 ' implementation 'com . huawei . hms : hianalytics : 5.0 .0 .301 ' implementation 'com . huawei . agconnect : agconnect - core : 1.2 .0 .300 ' implementation 'com . huawei . hms : base : 4.0 .1 .300 ' implementation 'com . huawei . hms : hwid : 4.0 .1 .300 ' implementation 'com . huawei . hms : game : 4.0 .1 .300 ' implementation 'com . huawei . hms : location : 4.0 .3 .301 ' } android { compileSdkVersion * * APIVERSION * * buildToolsVersion ' * * BUILDTOOLS * * ' compileOptions { sourceCompatibility JavaVersion . VERSION_1_8 targetCompatibility JavaVersion . VERSION_1_8 } defaultConfig { minSdkVersion * * MINSDKVERSION * * targetSdkVersion * * TARGETSDKVERSION * * applicationId ' * * APPLICATIONID * * ' ndk { abiFilters * * ABIFILTERS * * } versionCode * * VERSIONCODE * * versionName ' * * VERSIONNAME * * ' } aaptOptions { noCompress = [ ' . ress' , ' . resource' , ' . obb' ] + unityStreamingAssets . tokenize ( ' , ' ) ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" } * * SIGN * * lintOptions { abortOnError false } buildTypes { debug { minifyEnabled * * MINIFY_DEBUG * * proguardFiles getDefaultProguardFile ( 'proguard - android . txt' ) * * SIGNCONFIG * * jniDebuggable true } release { minifyEnabled * * MINIFY_RELEASE * * proguardFiles getDefaultProguardFile ( 'proguard - android . txt' ) * * SIGNCONFIG * * } } * * PACKAGING_OPTIONS * * * * SPLITS * * * * BUILT_APK_LOCATION * * bundle { language { enableSplit = false } density { enableSplit = false } abi { enableSplit = true } } } * * SPLITS_VERSION_CODE * * * * LAUNCHER_SOURCE_BUILD_SETUP * *
5,baseProjectTemplate.gradle
    
    
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN allprojects { buildscript { repositories { * * ARTIFACTORYREPOSITORY * * google ( ) jcenter ( ) maven { url 'https : / / developer . huawei . com / repo / ' } } dependencies { // If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity // See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html // See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle // To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version classpath 'com . android . tools . build : gradle : 3.6 .0 ' classpath 'com . huawei . agconnect : agcp : 1.2 .1 .301 ' * * BUILD_SCRIPT_DEPS * * } } repositories { * * ARTIFACTORYREPOSITORY * * google ( ) jcenter ( ) flatDir { dirs "${project(':unityLibrary').projectDir}/libs" } maven { url 'https : / / developer . huawei . com / repo / ' } } } task clean ( type : Delete ) { delete rootProject . buildDir }

3,生成签名证书

在本流程中,可利用Unity编辑器来生成签名证书
Keytore... -> create new
注意:
生成并记住证书保存的路径,稍后将需要文件路径创建签名证书指纹!
设定并记住密码,并在最终构建前需要输入密码,否则无法成功构建!

4,生成签名证书指纹

在命令窗口,通过Keytool工具以及签名文件保存路径下的签名文件及验证密码,导出SHA256指纹。
Windows:
打开命令窗口,在安装JDK的bin目录下运行,输入keytool查看签名文件指令,并运行。 keytool -list -v -keystore D:\Android\WorkSpcae\HmsDemo\app\HmsDemo.jks 在信息中输入签名文件密钥库口令(口令即生成签名文件时的Password) 获取对应SHA256指纹。
MacOS:
在Terminal终端输入keytool查看签名文件指令,并运行。 keytool -list -v -keystore /Users/admin/Downloads/HmsDemo.jks 在信息中输入签名文件密钥库口令(口令即生成签名文件时的Password)。 获取对应SHA256指纹。
参照华为 HMS Core集成准备 Step4 生成SHA256证书指纹
生成/配置签名证书以及指纹的详情,可参考华为文档说明: https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#2

5,回到华为添加指纹证书

参照华为 HMS Core集成准备 Step5 在AppGAllery Connect里添加指纹。

6,下载并添加Agconnect-services.json 到Unity项目

下载 agconnect-services 的json文件
从华为开发者账号内下载此json 文件后,在其中加入以下信息。
    
    
"agcgw" : { "backurl" : "connect-drcn.dbankcloud.cn" , "url" : "connect-drcn.hispace.hicloud.com" } ,
加入所需信息后,放回到Unity项目中此文件夹路径之下
Assets/Plugins/Android

7,设置构建包名,及其他设置

Edit -> Project Settings -> Player
构建的包名由如下组成 com.${Company Name}.${Product Name} 同时也可以在此步骤完成其余的所需设置,比如您的应用版本号、应用的图标、设置显示的分辨率等……
备注:Get Activity 如果需要在项目中调用华为函数,可使用
    
    
Common . GetActivity ( )

三,SDK集成开发

本程序包中目前集成华为广告服务的广告形式有两种,分别为“Rewarded Ads激励式广告” 和 “Interstitial插播式广告”。最终完成我们将需要完成:
  1. 创建广告的点击入口
  2. 获取广告
  3. 展示广告
  4. 更多华为广告Api功能的调用
  5. 挂载脚本到广告位
  6. 打包运行并完成效果测试
  7. 申请上架

1,创建广告的点击入口

我们以一个最简单的Unity Roll a Ball项目为例。当玩家失败后可通过点击观看广告获得生命。
在Canvas分别创建“Rewarded Ads激励式广告”(视频广告)和“Interstitial插播式广告”(图像广告)两个Button按钮式 广告位入口。

2,获取广告

用loadAd()方法来获取广告 用你之前在华为账号内获取的真实广告ID替换代码中的测试ID
    
    
using UnityEngine ; using HuaweiService ; using HuaweiService . ads ; //获取华为图片广告 public void LoadImageAds ( ) { InterstitialAd ad = new InterstitialAd ( new Context ( ) ) ; ad . setAdId ( "teste9ih9j0rc3" ) ; //此处为测试广告ID ad . setAdListener ( new MAdListener ( ad ) ) ; AdParam . Builder builder = new AdParam . Builder ( ) ; AdParam adParam = builder . build ( ) ; ad . loadAd ( adParam ) ; } //获取华为视频广告 public void LoadVideoAds ( ) { InterstitialAd ad = new InterstitialAd ( new Context ( ) ) ; ad . setAdId ( "testb4znbuh3n2" ) ; //此处为测试广告ID ad . setAdListener ( new MAdListener ( ad ) ) ; AdParam . Builder builder = new AdParam . Builder ( ) ; ad . loadAd ( builder . build ( ) ) ; } //获取华为激励式广告 public void LoadRewardAds ( ) { RewardAd ad = new RewardAd ( new Context ( ) , "testx9dtjwj8hp" ) ; //此处为测试广告ID AdParam adParam = new AdParam . Builder ( ) . build ( ) ; MRewardLoadListener rewardAdLoadListener = new MRewardLoadListener ( ad ) ; ad . loadAd ( adParam , rewardAdLoadListener ) ; }

3,监听广告事件

通过实现AdListener类中的方法来监听广告事件
    
    
using HuaweiService ; using HuaweiService . ads ; namespace HuaweiServiceDemo { public partial class Util { public static void showToast ( string message ) { Toast . makeText ( new Context ( ) , message , Toast . LENGTH_SHORT ) . show ( ) ; } } public class MAdListener : AdListener { private InterstitialAd ad ; public MAdListener ( InterstitialAd _ad ) : base ( ) { ad = _ad ; } public override void onAdLoaded ( ) { Util . showToast ( "AdListener onAdLoaded" ) ; TestTip . Inst . ShowText ( "AdListener onAdLoaded" ) ; ad . show ( ) ; } public override void onAdFailed ( int arg0 ) { Util . showToast ( $"Ad failed to load with error code { arg0 } ." ) ; } public override void onAdOpened ( ) { Util . showToast ( "Ad Opened" ) ; } public override void onAdClicked ( ) { Util . showToast ( "Ad Clicked" ) ; } public override void onAdLeave ( ) { Util . showToast ( "Ad Leave" ) ; } public override void onAdClosed ( ) { Util . showToast ( "Ad Closed" ) ; } } public class MRewardLoadListener : RewardAdLoadListener { private RewardAd ad ; public MRewardLoadListener ( RewardAd _ad ) { ad = _ad ; } public override void onRewardAdFailedToLoad ( int errorCode ) { Util . showToast ( "RewardAdLoadListener onRewardAdFailedToLoad " + errorCode ) ; TestTip . Inst . ShowText ( "RewardAdLoadListener onRewardAdFailedToLoad " + errorCode ) ; } public override void onRewardedLoaded ( ) { Util . showToast ( "RewardAdLoadListener onRewardedLoaded" ) ; TestTip . Inst . ShowText ( "RewardAdLoadListener onRewardedLoaded" ) ; ad . show ( new Context ( ) , new MRewardAdStatusListener ( ) ) ; } }

4,更多高级Api功能的调用

    
    
//基于受众人群的设置 public void setRequestOptionsNonPersonalizedAd ( ) { RequestOptions reqOptions = HwAds . getRequestOptions ( ) . toBuilder ( ) . setNonPersonalizedAd ( new Integer ( NonPersonalizedAd . ALLOW_ALL ) ) . build ( ) ; HwAds . setRequestOptions ( reqOptions ) ; TestTip . Inst . ShowText ( "RequestOptions NonPersonalizedAd:" + HwAds . getRequestOptions ( ) . getNonPersonalizedAd ( ) ) ; } //征求用户意见获取广告 public void SetConsentStatus ( bool personal ) { Consent consentInfo = Consent . getInstance ( new Context ( ) ) ; var consentStatus = personal ? ConsentStatus . PERSONALIZED : ConsentStatus . NON_PERSONALIZED ; consentInfo . setConsentStatus ( consentStatus ) ; Util . showToast ( $"set consent status as { consentStatus } " ) ; } //更新用户意见状态 public void checkConsentStatus ( ) { Consent consentInfo = Consent . getInstance ( new Context ( ) ) ; consentInfo . requestConsentUpdate ( new MConsentUpdateListener ( ) ) ; }

5,挂载脚本到广告位

  • 选中Canvas上的“Interstitial插播式广告”广告位(举例:HuaweiImageAds)
  • 将上述脚本挂载上去(举例:RewardedAdsButton)
  • 在Button的OnClick() 上定义调用上述脚本以及脚本内对应的函数(举例:LoadImageAds() )
“Rewarded Ads激励式广告”广告位(举例:HuaweiVideoAds)脚本挂载方法同上!

6,打包运行并完成效果测试

输入签名证书Key及密码
Project Settings --> Player --> Publish Settings
Build and run并得到APK
确认SDK集成效果:

7,申请上架

至此,你的移动应用APK内已集成了华为广告流量变现服务。
接下来,请参考华为文档,对应用进行上架前的确认,并申请上架。祝您成功! https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/pre-release-check-0000001050064994

辅助信息:

关于其他华为HMS / AGC 服务的基本集成步骤,请参阅以下Unity在线文档进行代码编写并完成SDK的集成: https://docs.unity.cn/cn/Packages-cn/com.unity.huaweiservice@1.3/manual/index_cn.html
同时,强烈建议下载中国Unity在Github上的开源示例项目,根据其中所需集成的具体服务进行参考: https://github.com/Unity-Technologies/HuaweiServiceSample 在示例项目中,对应的场景是:
Assets/HuaweiServiceDemo/Scenes/HmsAdsSampleScene.unity
而对应的代码是:
Assets/HuaweiServiceDemo/demo/test/ads/AdsTest.cs
Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐