Unity和Android的交互原理

一、應用場景

如果在unity中需要調用android原生的方法,或者anrdroid項目中需要調用unity中的方法實現就需要用到unity和androd之間的相互通信了。

二、在Unity中調用Android的方法

1、在Android項目中新建一個module
在這裏插入圖片描述
2、類型選擇「Android Library」
在這裏插入圖片描述
Application/Library name認真填寫,之後爲arr導出的名稱,這裏我們叫「MyUnityLib」。

Module name沒有強迫症就不用管它

Package name認真填寫,之後unity裏會用到,不過它和unity導出的包名沒有什麼關係這裏我們叫「com.jing.unity」好了

Minimum SDK能選多低選多低,反正不超過unity發佈的版本就行
在這裏插入圖片描述
3、然後我們在com.jing.unity包下創建一個類,作爲Unity和Android通信的核心類,名字儘量炫酷一點,這裏我們叫「Unity2Android」
在這裏插入圖片描述
4、編寫Android端代碼
然後我們直接粘貼該類的代碼,講解直接看註釋。這裏我們通過Java的反射原理來獲取本來導入class.jar類才能引用到的com.unity3d.player.UnityPlayer包下的currentActivity上下文。同理給unity發消息也是反射原理。「getActivity」和「callUnity」這兩個方法,有一定的開發經驗應該很容易理解。
這裏我們實現一個簡單的接口「showToast」。

     package com.jing.unity;
     
     import android.app.Activity;
     import android.widget.Toast;
     
     import java.lang.reflect.InvocationTargetException;
     import java.lang.reflect.Method;
     
     /**
      * Created by Jing on 2018-1-18.
      */
     public class Unity2Android {
     
         /**
          * unity項目啓動時的的上下文
          */
         private Activity _unityActivity;
         /**
          * 獲取unity項目的上下文
          * @return
          */
         Activity getActivity(){
             if(null == _unityActivity) {
                 try {
                     Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
                     Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);
                     _unityActivity = activity;
                 } catch (ClassNotFoundException e) {
     
                 } catch (IllegalAccessException e) {
     
                 } catch (NoSuchFieldException e) {
     
                 }
             }
             return _unityActivity;
         }
     
         /**
          * 調用Unity的方法
          * @param gameObjectName    調用的GameObject的名稱
          * @param functionName      方法名
          * @param args              參數
          * @return                  調用是否成功
          */
         boolean callUnity(String gameObjectName, String functionName, String args){
             try {
                 Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
                 Method method =classtype.getMethod("UnitySendMessage", String.class,String.class,String.class);
                 method.invoke(classtype,gameObjectName,functionName,args);
                 return true;
             } catch (ClassNotFoundException e) {
     
             } catch (NoSuchMethodException e) {
     
             } catch (IllegalAccessException e) {
     
             } catch (InvocationTargetException e) {
     
             }
             return false;
         }
     
         /**
          * Toast顯示unity發送過來的內容
          * @param content           消息的內容
          * @return                  調用是否成功
          */
         public boolean showToast(String content){
             Toast.makeText(getActivity(),content,Toast.LENGTH_SHORT).show();
             //這裏是主動調用Unity中的方法,該方法之後unity部分會講到
             callUnity("Main Camera","FromAndroid", "hello unity i'm android");
             return true;
         }
     }

5、導出arr準備給unity使用
代碼寫好了我們選中module然後選擇「Build」「Rebuild Project」
在這裏插入圖片描述
接着將這個arr文件找到,就是我們要導入到unity的文件了。

6、Unity部分Script的代碼內容如下

using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour {

    /// <summary>
    /// 場景上的文本框用來顯示android發送過來的內容
    /// </summary>
    public Text text;

    /// <summary>
    /// android原生代碼對象
    /// </summary>
    AndroidJavaObject _ajc;

    void Start () {
        //通過該API來實例化導入的arr中對應的類
        _ajc = new AndroidJavaObject("com.jing.unity.Unity2Android");
    }
    
    void Update () {
        
    }

    /// <summary>
    /// 場景上按點擊時觸發該方法
    /// </summary>
    public void OnBtnClick()
    {
        //通過API來調用原生代碼的方法
        bool success = _ajc.Call<bool>("showToast","this is unity");
        if(true == success)
        {
            //請求成功
        }
    }

    /// <summary>
    /// 原生層通過該方法傳回信息
    /// </summary>
    /// <param name="content"></param>
    public void FromAndroid(string content)
    {
        text.text = content;
    }
}

三、在Android中調用unity中的代碼

以上我們實現了unity上調用android的方法,那麼android上如何調用unity的方法呢,我們先回到unity的AndroidControl腳本。添加方法OnTimeResult,注意在這裏需要導入UnityEngine.UI包usingUnityEngine.UI;

public void OnTimeResult (string result)
    {
        Text text = GameObject.Find ("TimeShow").GetComponent<Text> ();
        text.text = result;
    }

上面代碼的意思是獲取名稱爲TimeShow的對象,然後將該對象上的Text腳本的文本改爲得到的result。所以我們需要將之前的Text對象名稱改爲TimeShow

回到android的MainActivity,修改方法showToast,讓Toast時間的時候同時調用OnTimeResult方法修改text的文本。

public void showToast(final String text) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {

            public void run() {
                if (mToast == null) {
                    mToast = Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT);
                } else {
                    mToast.setText(text);
                }
                mToast.show();
                UnityPlayer.UnitySendMessage("Canvas","OnTimeResult",text);
            }
        });
    }

UnityPlayer.UnitySendMessage(“Canvas”,“OnTimeResult”,text);方法的意思是調用名稱爲Canvas對象上的OnTimeResult方法,傳入的參數爲text。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章