The small game made by myself needs to be connected with advertisements. I have tried UnityAds and AdMob before, but both of them have some minor problems. UnityAds is not good for domestic and local support, Banner ads often have no content (VPN switch to the United States, there is). Admob basically has to connect to googlePlay. Then I looked for the domestic advertising SDK.

It’s been a long time, the tutorials on the web are old, and I’m completely new to AndroidStudio (this tutorial was written in September 2020, using the V3.0 SDK).

The preparatory work

  1. Create an account www.pangle.cn/
  2. Add application
  3. Add code bits (AD bits)
  4. Download SDK(Access Center – Pangolin SDK Unity plug-in)

Why choose Unity plugin instead of native? It’s easy. I don’t do Android and IOS development

Part of Unity work

  • Open Unity (I’m using 2019.4.10, different versions of the exported AndroidStudio project are different, more on that later)
  • The import plug-in

Both of them come in

  • Double click to open the Example/Example scenario and publish the project. You can’t package it as APK directly.
  • Export the 2019 version:

Just check Export Project and click Export

  • 2018 Export method: BuildSystem select Gradle, check Export Project, and click Export

Please check the package Settings of ProjectSetting

AndroidStudio part of the work

  • Open the exported project with AndroidStudio

Just pop the option OK and wait for the syncing (which may be slow)

  • Switch to Project mode and now you have the Project directory

  • Click unityLibrary-src-main-java, right-click java-new-package, name com.bytedance.android

The finished structure

  • Open the case folder imported into Unity

Copy the scripts in the red box below the newly created Package

The finished structure

  • Then you can package the test case scenarios directly. Build-Build Bundle(s)/APK(s) -build APK(s) (the output apk will be installed on the phone in the current AndroidStudio project directory launcher build-outputs apk-debug.)

If the project is exported from Unity2018 or the following version

  • The location of the new Package is here:

The remaining steps are the same

Set it to your own project

  • Open UnionApplication.java and change the appId and appName to the project you created on the site

  • In the Load AD cs code, change the CodeId to the code bit ID you added

Call the advertising

  • Load first, then Show, the specific call method is in the example. cs script, directly copy
  • See the documentation for specific Api instructions

IOS

  • Modify the unionAppController.mm configuration in Example

  • Compile xcode directly and run it to see if there are any problems. If there are problems, put unionAppController.mm in unity’s Plugins/IOS directory and recompile

Modify Banner AD position

Android

  • Find the Java script in Unity: nativeAdManager.java
  • Find the showExpressBannerAd() method in the script and modify onRenderSuccess(),
layoutParams.gravity = Gravity.CENTER | Gravity.BOTTOM; // The Banner is in the middle of the bottom of the application
layoutParams.gravity = Gravity.CENTER | Gravity.TOP;// The Banner is located in the middle of the top of the application
Copy the code

Remember, change it in Unity and export the package, don’t export the package and change it in AndroidStudio (I don’t know why, it’s all after I tried).

IOS

  • Set the placement of the AD in the display Banner AD code you wrote yourself:
public void ShowExpressBannerAd()
{
#if UNITY_IOS
        if (iExpressBannerAd == null)
        {
            Debug.LogError("Please load the AD first.");
            return;
        }

        // the coordinates are based on the top left vertex of the Banner AD, so (0,0) is located at the top of the screen
        // If the AD width set during load is not equal to the screen width, you need to calculate the x coordinate yourself
        int x = 0;
        int y = Screen.height - (Screen.width / 640 * 100);

        // If the Banner is at the top of the app, add some macros. If the iPhone has bangs, make y=100 to avoid being obscured by bangs. My Banner is at the bottom of the screen, so I don't need it
        //if (y == 0)
        / / {
        // y = 100; // Prevent bangs in Demo
        / /}

        iExpressBannerAd.ShowExpressAd(x, y);
#else
        // Display code for Android
#endif
}
Copy the code

Various pit solutions

  1. Do not use NativeBannerAd, NativeIntersitialad, etc. Native ads are not officially supported, use template ads, that is, the Express bannerad method in Example script.
  2. I thought that the Java script stored in Unity project would not affect the AndroidStudio project, but I never thought that the corresponding AndroidStudio script would change when packaged. Therefore, the Java script in the Example folder can be directly changed to its own appID. In case it’s packaged and turned into a test appID. (This problem is the unity2019 version, because in this version, Unity will automatically compile the Java script and Xcode project script in the project, so you can directly modify it in Unity and then compile it.)
  3. Android: Theme =”@style/UnityThemeSelector”

Here is my full androidmanifest.xml version

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.product">

    <! -- Required permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <! -- The best permission to provide -->
    <! --<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->

    <! -- If you have a video related advertisement and use textureView to play, please add it, otherwise black screen -->
    <! --<uses-permission android:name="android.permission.WAKE_LOCK" />-->
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>
    <application
        android:name="com.bytedance.android.UnionApplication"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:theme="@style/UnityThemeSelector"
        android:allowBackup="true"
        android:debuggable="true"
        android:supportsRtl="true">
        <uses-library android:name="org.apache.http.legacy" android:required="false"/>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
             android:label="@string/app_name"
             android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMo de|touchscreen">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data android:name="android.app.lib_name" android:value="unity"/>
        <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false"/>
    </activity>
     <provider
            android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
            android:authorities="${applicationId}.TTFileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

        <provider
            android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
            android:authorities="${applicationId}.TTMultiProvider"
            android:exported="false" />
    </application>
</manifest>
Copy the code
  1. Apple package compiler real machine debugging error

As you can see from the LoadExpressRewardAd() method, just fill in all the required parameters in the AdSlot

  1. On Android devices, motivational video ads cut back in the background in the middle of a play, and the ads simply disappear.

Solutions: The launchMode of your activity is singleTask, singleTop, singlettop, singletTop, singletTop, SingletTop, SingletTop, SingletTop, SingletTop, SingletTop, SingletTop Unity forces Unity to set it to singleTask

  1. When upgrading the latest Android and ios SDKS using the Unity plugin, download the latest corresponding SDK directly from the official source. Android replaces Plugins/Android/ open_ad_SDK. aar with open_ad_sdK. aar in the Android SDK. IOS replaces buadsdK. bundle, buadsdK. framework, and BUFoundation. Framework in Plugins/IOS with Frameworks in IOS SDK.

FullScreenVideoAD and RewardVideoAD will not load if they are packaged directly after the upgrade. You need to add adSlot in the method of loading these two ads. SetExpressViewAcceptedSize (400, 80) parameter, as long as the parameter is not zero.

  1. The banner advertisement position on ios devices is inappropriate. I myself worked fine on the iphoneSE and iphoneX, at the bottom of the screen, but on the iphone8plus, the position ran away. I consulted the work order submitted to Pangolin, saying that it was due to unity’s own bug that the screen size obtained was incorrect, so we need to modify the script in Xcode project. The solution is as follows:

In the Xcode project, find the expressBannerad. mm method UnionPlatform_ExpressBannersAd_Load, and then set the size of the banner, Then in the UnionPlatform_ExpressBannersAd_Show method, reset the position of the banner. Just look at the few lines I annotated.

    void UnionPlatform_ExpressBannersAd_Load(
                                      const char* slotID,
                                      float width,
                                      float height,
                                      BOOL isSupportDeepLink,
                                      ExpressAd_OnLoad onLoad,
                                      ExpressAd_OnLoadError onLoadError,
                                      int context) {
        ExpressBannerAd *instance = [[ExpressBannerAd alloc] init];
        
        CGFloat newWidth = width/[UIScreen mainScreen].scale;
        CGFloat newHeight = height/[UIScreen mainScreen].scale;
                 
        // Re-assign newWidth to the current screen width, and then fix the banner AD width to the current screen width
        newWidth = [UIScreen mainScreen].bounds.size.width;
        newHeight = newWidth / 640 * 100;

        if (0) {
            instance.bannerView = [[BUNativeExpressBannerView alloc] initWithSlotID:[[NSString alloc] initWithUTF8String:slotID] rootViewController:GetAppController().rootViewController adSize:CGSizeMake(newWidth, newHeight) IsSupportDeepLink:YES interval:30];
        } else {
            instance.bannerView = [[BUNativeExpressBannerView alloc] initWithSlotID:[[NSString alloc] initWithUTF8String:slotID] rootViewController:GetAppController().rootViewController adSize:CGSizeMake(newWidth, newHeight) IsSupportDeepLink:YES];
        }
        instance.bannerView.frame = CGRectMake(0.CGRectGetHeight([UIScreen mainScreen].bounds)-newHeight, newWidth, newHeight);
        instance.bannerView.delegate = instance;
        instance.onLoad = onLoad;
        instance.onLoadError = onLoadError;
        instance.loadContext = context;
        [instance.bannerView loadAdData];
        
        // Strong hold, is the reference plus +1
        [[BUToUnityAdManager sharedInstance] addAdManager:instance];
        
        (__bridge_retained void*)instance;
    }
Copy the code
    void UnionPlatform_ExpressBannersAd_Show(void* expressAdPtr, float originX, float originY) {
        ExpressBannerAd *expressBannerAd = (__bridge ExpressBannerAd*)expressAdPtr;
        
        CGFloat newX = originX/[UIScreen mainScreen].scale;
        CGFloat newY = originY/[UIScreen mainScreen].scale;
        
        // recalculate the banner AD position
        / / at the bottom:
        newX = 0;
        newY = [UIScreen mainScreen].bounds.size.height - expressBannerAd.bannerView.frame.size.height;

        expressBannerAd.bannerView.frame = CGRectMake(newX, newY, expressBannerAd.bannerView.frame.size.width, expressBannerAd.bannerView.frame.size.height);
        
        [GetAppController().rootViewController.view addSubview:expressBannerAd.bannerView];
    }
Copy the code

Or unity2019 above, you can also directly find the corresponding script in Unity, modify and compile.