【Unity遊戲開發】SDK接入與集成——小白入門篇

1、簡介

  一般一款遊戲開發到後期,通常都會涉及到第三方SDK的接入與集成,對於不熟悉SDK接入的同窗來講,接SDK每次都是雲裏霧裏,而熟悉SDK接入的同窗又以爲不斷地重複作接入SDK工做這樣沒有成就感,太尼瑪無聊了(Android渠道一弄就十幾個,直接吐血)。其實一般狀況下接入SDK都是很簡單的一個過程,本系列博客就讓馬三和你們從小白開始,從零基礎開始學習如何接入SDK以及一些常見的SDK的接入流程。本系列博客規劃爲如下幾篇:html

  • SDK接入與集成——小白入門篇(介紹環境搭建以及Unity和Android的基本交互與調用)
  • SDK接入與集成——信鴿SDK篇(介紹消息推送框架--信鴿SDK的接入)
  • SDK接入與集成——QQ與微信SDK篇(都是騰訊開放平臺的,就放在一塊兒學了)
  • SDK接入與集成——科大訊飛SDK篇(遊戲中的語音通訊和語音識別會用到此SDK)
  • SDK接入與集成——百度地圖SDK篇(作LBS遊戲必不可少)
  • SDK接入與集成——第三方SDK接入解決方案AnySDK篇
  • SDK接入與集成——構建本身的Android集成多SDK框架篇

  先挖了這麼多坑,之後慢慢填吧,放心博主確定不會太監的。java

2、淺談經常使用的兩種接入方案

1.第三方SDK接入解決方案

  其實遊戲SDK接入發展到如今,已經有不少成熟的第三方SDK接入解決方案了,好比AnySDK,ShareSDK,U8SDK等等。這些第三方SDK接入解決方案的整個接入過程,不改變任何SDK的功能、特性、參數等,對於最終玩家而言是徹底透明無感知的。讓CP商能有更多時間更專一於遊戲自己的品質。第三方SDK包括了渠道SDK、用戶系統、支付系統、廣告系統、統計系統、分享系統等等。利用他們能夠輕鬆快速接入第三方SDK。android

  第三方SDK的統一驗證流程基本以下:git

  

2.手動接入SDK

  既然上面說的第三方解決方案那麼好,爲何咱們還有手動去接入SDK呢?造輪子就這麼上癮?其實接入了一些第三方的SDK解決方案之後,咱們有的遊戲數據是要通過他們的服務器的,對於一些遊戲廠商來講,不想讓本身的數據通過別人的服務器,或者須要對驗證服務器有徹底自主的控制權,那麼必然要手動接入各類SDK了。另外還有一些奇奇怪怪,很是詭異的SDK,咱們也是要手動去接入的,不能都期望第三方的集成。並且做爲一名合格的猿類來講,知其然更要知其因此然,掌握SDK的接入原理和過程頗有必要。github

3、開始接入!Unity與Android的交互

  前面囉嗦了那麼多,到這裏終於能夠開始實戰操做了。服務器

1.Android開發環境搭建

  關於Android環境的搭建,網上已經有不少博客了,介紹的很詳細,馬三就不在這裏水了。這裏給你們安利一個關於Android開發工具的好網站:http://www.androiddevtools.cn/ 。上面提供了不少可用的AndroidADK國內鏡像和教程。微信

2.Android端的開發工做

  (1)打開IDE創建一個空的Android庫工程,這裏我用Eclispe舉例。注意Min Required SDK最好選擇4.0以上,要否則還須要引入android-support-v7兼容包,比較麻煩,以後咱們能夠把這個Min Required SDK 再該回來的。須要注意的兩步已經截圖了,剩下一路Next操做便可。注意包名和勾選Mark this project as a library選項。app

  

  (2)導入Classes.jar包到Android工程中框架

  Unity和Android作交互,他們兩個之間不認識確定,無法直接通訊,所以須要一箇中間的搭橋牽線的人,Classes.jar就起到了這個做用。Classes.jar是由Unity提供給咱們的,咱們須要找到它而且引入到咱們的Android項目中。Claess.jar的路徑通常以下 X盤:\xxx目錄\Unity\Editor\Data\PlaybackEngines\androidplayer\release\bin\classes.jar(不一樣的計算機上,這個位置可能會有所不一樣,你們按照本身的路徑添加便可)。咱們找到它直接拖到咱們的Android工程的libs目錄下。而後在它上面右鍵,將其添加到Build Path中。編輯器

  

  添加到Build Path成功之後,工程是這個樣子的。

  

  (3)編寫Android端的代碼

  咱們在Android端編寫一些代碼,提供一些接口來供Unity一會的調用。打開咱們的MainActivity.java,而後添加代碼。須要注意的是,讓咱們的MainActivity繼承Jar包中的UnityPlayerActivity類,這樣,Unity才能調的到哦,缺什麼包,直接讓Eclipe自動導下包便可,快捷鍵ctrl+shift+o。對了,還須要把 setContentView(R.layout.activity_main); 這段代碼註釋掉,要否則會顯示Android的默認佈局文件,上面就一個 Hello World。

  

 

  簡單的寫了幾個普通方法和一個靜態方法,供一會的測試調用。(不管是靜態方法仍是普通方法,在Unity中都是能夠調用的到的)MainActicity.java的代碼內容以下:

 1 package com.mx.sdkbase;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.Menu;
 6 import android.view.MenuItem;
 7 import android.widget.Toast;
 8 
 9 import com.unity3d.player.UnityPlayer;
10 import com.unity3d.player.UnityPlayerActivity;
11 
12 public class MainActivity extends UnityPlayerActivity {
13 
14     private static MainActivity instance;
15 
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         // setContentView(R.layout.activity_main);
20 
21         instance = this;
22     }
23 
24     @Override
25     public boolean onCreateOptionsMenu(Menu menu) {
26         // Inflate the menu; this adds items to the action bar if it is present.
27         getMenuInflater().inflate(R.menu.main, menu);
28         return true;
29     }
30 
31     @Override
32     public boolean onOptionsItemSelected(MenuItem item) {
33         // Handle action bar item clicks here. The action bar will
34         // automatically handle clicks on the Home/Up button, so long
35         // as you specify a parent activity in AndroidManifest.xml.
36         int id = item.getItemId();
37         if (id == R.id.action_settings) {
38             return true;
39         }
40         return super.onOptionsItemSelected(item);
41     }
42 
43     
44     /**
45      * 供Unity調用的求和函數
46      * @param x
47      * @param y
48      * @return
49      */
50     public int Sum(int x, int y) {
51         return x + y;
52     }
53 
54     /**供Unity調用的比較最大值函數
55      * @param x
56      * @param y
57      * @return
58      */
59     public int Max(int x, int y) {
60         return Math.max(x, y);
61     }
62 
63     
64     /**供Unity調用的顯示吐司的函數
65      * @param str
66      */
67     public void MakeToast(String str) {
68         Toast.makeText(this, str, Toast.LENGTH_LONG).show();
69     }
70 
71     
72     /**供Unity調用的自加一函數
73      * @param x
74      * @return
75      */
76     public int AddOne(int x) {
77         return x + 1;
78     }
79 
80     
81     /**供Unity調用的靜態方法,單例類,返回當前的Activity對象
82      * @return
83      */
84     public static MainActivity GetInstance() {
85         return instance;
86     }
87     
88     
89     /**供Unity調用的函數,此函數會回調指定的一個Unity中的方法,完成數據的雙向交互
90      * @param str
91      */
92     public void CallUnityFunc(String str){
93         str=str+"Android Call Unity.";
94         String ReceiveObject="MessageHandler";
95         String ReceiverMethod="Receive";
96         UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
97     }
98 }

 

   (4)導出咱們的Android項目爲Jar包供Unity調用

  在咱們的項目上面右鍵,而後選擇Export,選擇Java目錄下的 Jar file。由於沒有用到第三方的jar包或者lib庫,所以只要勾選src/和res/目錄導出爲jar包便可。

  

  (5)Unity端工程的開發

  創建一個新的空Unity工程,而後在Asset/目錄下創建以下路徑的文件夾:Plugins/Android。從名字就能夠看出來,這個文件夾是用來存放安卓的插件的。而後將咱們上面剛剛導出的SDKBase.jar 包導入到這個目錄下,而且將Andoird工程目錄下的,libs/ 、res/ 、AndroidMainFest.xml 都複製到該路徑下。

  須要特別注意的是要將Unity 項目中 libs下的classes.jar文件刪除掉,這個就是上面提到的那個起到中介做用的jar包,必定要刪掉!必定要刪掉!必定要刪掉!(重要的事情說三遍,網上很多教程都是針對Unity老版的教程,沒有提到要刪除這個classes.jar包,結果在Unity 5.x中打包確定會出錯)。出錯截圖以下所示。

   

  而後咱們創建一個場景,簡單地在裏面放上一些Label和輸入框、按鈕,供咱們驗證交互操做。而且編寫一個腳本(MessageHandler.cs便是我建立的腳本), 在其中編寫用來調用Jar包的C#方法,而後將按鈕和這些函數綁定(Unity基本操做,不贅述了)。

   

  MessageHandler.cs 腳本的內容以下,函數的功能看註釋就好了,寫得很全。

 1 using System;
 2 using UnityEngine;
 3 using UnityEngine.UI;
 4 
 5 public class MessageHandler : MonoBehaviour
 6 {
 7     private AndroidJavaClass _jc;
 8     private AndroidJavaObject _jo;
 9 
10     public InputField inputFieldA;
11     public InputField inputFiledB;
12     public Text resultLabel;
13 
14     // Use this for initialization
15     void Start()
16     {
17         //初始化
18         //"com.unity3d.player.UnityPlayer"和"currentActivity"這兩個參數都是固定的
19         //UnityPlayerActivity裏面對其進行了處理
20         _jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
21         _jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");
22     }
23 
24     public void AddOne()
25     {
26         int a = Convert.ToInt32(inputFieldA.text);
27 
28         //注意,這裏使用的就不是以前默認的com.unity3d.player.UnityPlayer,而是須要傳入本身的類(實現了須要調用相應方法的類)
29         //由於默認的UnityPlayer中是沒有咱們所須要的方法的,因此須要加載本身的類
30         AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");
31         //調用Java中的靜態方法,單例模式,返回當前Activity實例
32         AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");
33         resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);
34     }
35 
36     public void Sum()
37     {
38         int a = Convert.ToInt32(inputFieldA.text);
39         int b = Convert.ToInt32(inputFiledB.text);
40         //調用Java類中的普通方法,返回值爲int型
41         resultLabel.text = "Sum: " + _jo.Call<int>("Sum", a, b);
42     }
43 
44     public void Max()
45     {
46         int a = Convert.ToInt32(inputFieldA.text);
47         int b = Convert.ToInt32(inputFiledB.text);
48         resultLabel.text = "Max: " + _jo.Call<int>("Max", a, b);
49     }
50 
51     public void CallUnityFunc()
52     {
53         //調用Java中的一個方法,該方法會回調Unity中的指定的一個方法,這裏會回調Receive( )
54         _jo.Call("CallUnityFunc","Unity Call Android.\n");
55     }
56 
57     public void Receive(string str)
58     {
59         resultLabel.text = str;
60     }
61 
62     public void Toast()
63     {
64         _jo.Call("MakeToast","Unity 調用Toast");
65     }
66 }

 

  經過上面的代碼,咱們就能夠看出來,想在Unity中調用Android的代碼,主要涉及到了兩個類。AndroidJavaClass 和 AndroidJavaObject 。這兩個類在Unity API手冊裏面有詳細的解釋。

  下面的代碼是獲取到對應包名的java.lang.Class實例,這裏獲取到的是com.unity3d.player.UnityPlayer類。

_jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

  下面的代碼是獲取到UnityPlayer類中的靜態字段,它的返回值類型是AndroidJavaObject對象。

_jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");

  經過以上兩行代碼,咱們能夠獲取到這個AndroidJavaObject 對象,而後用 AndroidJavaObject 對象就能夠任意地調用Android中的靜態和非靜態函數了。其中兩個函數中的字符串參數 "com.unity3d.player.UnityPlayer" 和 "currentActivity" 都是固定的寫法,咱們不用去改變。

  AndroidJavaObject 類的一些經常使用方法及功能以下表所示:

AndroidJavaObject 構造函數,根據類名返回AndroidJavaObject對象
Call 調用Android代碼中的非靜態方法
CallStatic 調用Android代碼中的靜態方法
Dispose IDisposable 回調
Get 獲取Android代碼中的非靜態字段
GetRawClass 獲取一個指向Java class的原始引用
GetRawObject 獲取一個指向Java object的原始引用
GetStatic 獲取Android代碼中的靜態字段
Set 設置Android代碼中的非靜態字段
SetStatic 設置Android代碼中的靜態字段

 

  另外,咱們還有第二種方法去訪問Java的代碼,那就是利用咱們以前在Java代碼中寫的 GetInstance() 靜態方法,它會返回一個MainActivity的實例,咱們拿到這個實例之後,就能訪問裏面的方法和字段了。須要注意的是此時的AndroidJavaClass構造函數中傳遞的字符串就不是 "com.unity3d.player.UnityPlayer" 了。而是要傳入本身的包名,好比代碼中的 「com.mx.sdkbase.MainActivity」 。代碼以下:

        int a = Convert.ToInt32(inputFieldA.text);

        //注意,這裏使用的就不是以前默認的com.unity3d.player.UnityPlayer,而是須要傳入本身的類(實現了須要調用相應方法的類)
        //由於默認的UnityPlayer中是沒有咱們所須要的方法的,因此須要加載本身的類
        AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");
        //調用Java中的靜態方法,單例模式,返回當前Activity實例
        AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");
        resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);

  不止Unity能夠調用Android的代碼,Android也能夠反過來回調Unity的代碼。下面這段代碼就是用來回調Unity函數的:

    /**供Unity調用的函數,此函數會回調指定的一個Unity中的方法,完成數據的雙向交互
     * @param str
     */
    public void CallUnityFunc(String str){
        str=str+"Android Call Unity.";
        String ReceiveObject="MessageHandler";
        String ReceiverMethod="Receive";
        UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
    }

  利用UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str); 就能夠返回過來回調一個Unity中的方法,完成Unity和Android的雙向通訊。其中第一個參數是接受該回調的gameobject名稱,第二個參數是掛載在該gameobject上面的一個腳本中接受該消息的方法,最後一個參數是本條消息發送的字符串信息。好比上面例子中的代碼就會調用名稱爲MessageHandler的gameobject上面掛載的腳本中的Receive方法。

  (6)打包發佈Android平臺的APK

  代碼寫好之後,咱們會習慣性地在Unity Editor 裏面運行查看一下效果,可是若是要調用 Android 代碼的話,是不能夠這樣作的,必定要在真機上運行(模擬器上也行),在Editor中運行會報錯的。因此咱們仍是打包發佈到Android端查看效果吧。

  在Unity中按快捷鍵 ctrl +b ,打開Build Setting界面,而後把平臺切換爲 Android 平臺並將咱們的測試場景加到Build Setting隊列中。點擊PlayerSetting,對工程的信息進行配置。注意要把裏面的Company Name和Product Name修改爲和包名一致。以下圖所示:

  

  而後 ,Bundle Identifier的值也要修改爲和包名同樣,而且調整下Minimum API Level。以下圖:

  

  最後,還記得咱們在最一開始創建Android庫工程的時候,將最小安裝需求的API調成了4.0嗎,這就意味着,打出來的APK包安裝運行的最低系統要求是Android 4.0。這樣確定是不能夠的,要考慮到低版本的Android系統。所以還須要作最後一步的修改,才能打包。

找到咱們Unity項目中的 AndroidManifest.xml 文件,用文本編輯器打開它,將android:minSdkVersion的值修改爲上一步在面板中設置的 Minimum API Level 對應的版本號,好比我這裏面的  Minimum API Level 爲2.3.3,其版本號爲 10。

  

  以後,咱們就能夠放心地打包了,打包成功後安裝到手機上測試下效果,下面是我在模擬器上測試的幾張效果圖:

    

   

  能夠看到Unity成功地調用到了Android中的方法,並返回正確的結果,並且Android反過來也回調了Unity中的方法。

4、結語

  關於「SDK接入與集成的小白入門篇」就寫到這裏了,經過本篇博客,咱們一塊兒初步地瞭解和學習了一下Unity和Android是如何交互的。下篇博客,咱們將會實戰地練習一下「消息推送框架」信鴿SDK的接入與使用,敬請期待!

  最後放上本篇博客中演示的項目源碼:

  Github地址:https://github.com/XINCGer/Unity3DTraining/tree/master/SDK/SDKBase    歡迎fork!

 

 

做者:馬三小夥兒
出處:http://www.cnblogs.com/msxh/p/7220741.html 請尊重別人的勞動成果,讓分享成爲一種美德,歡迎轉載。另外,文章在表述和代碼方面若有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!

相關文章
相關標籤/搜索