[填坑日记] Android Studio plugin to Unity

要开发Android的App有许多的方法,目前以Android Studio与Unity最为多人使用,而两者也都拥有完善的开发社群。刚好因为工作的关系,经常需要依照专案的属性选择开发的工具。例如 需要显示3D、有大量动画的专案会选择使用Unity进行开发。而需要一些Native的工具(BLE、Toast、Boardcast......)则会使用Android studio。

Android Stduio

优点:
-效能较佳
-有许多的Native API套件
-拥有庞大的Git library

缺点:
-视觉化界面较不完整
-开发时程相对较长

Unity

优点:
-较完整的视觉化界面
-对於3D的处理较容易
-Asset story提供许多工具
-跨平台
缺点:
-效能较差


碍於选择开发环境时,经常因为Android的功能并未支援Unity导致只能使用Android Studio开发,於是开始找方法该如何写Android plugins for Unity。这篇文章会用Unity呼叫Android Native的Toast作为范例。
废话到这 ~ 切入主题

首先建立Android Stduio专案

https://ithelp.ithome.com.tw/upload/images/20201016/201252983Eub9HLkA8.png
https://ithelp.ithome.com.tw/upload/images/20201016/20125298jXIsrMOqZE.png

Create new Module

https://ithelp.ithome.com.tw/upload/images/20201016/20125298gjD39y74vv.png
https://ithelp.ithome.com.tw/upload/images/20201016/20125298a9UazGMNMS.png

Create Java Class

在建立的Module路径下,新增一个新的JavaClass (这边取名也叫做JavaClass)
这边写了一个function被呼叫时会把得到的讯息跟TAG一起print在log上


public class JavaClass 
{
    private final String TAG ="JavaClass";
    
    public void logPrint (String message)
    {
        Log.i(TAG,message);
    }
}

https://ithelp.ithome.com.tw/upload/images/20201016/20125298SzGZIa7vtD.pnghttps://ithelp.ithome.com.tw/upload/images/20201016/20125298euguUHzM0y.png

Build Module

在路径下会产生一个class.jar
如果找不到的话可以在资料夹内搜寻 .jar
https://ithelp.ithome.com.tw/upload/images/20201016/20125298BHkAPz9P3n.png

Copy to Unity plugin

在Unity Assets中 Create Plugins/Android 的资料夹并将class.jar复制进去
https://ithelp.ithome.com.tw/upload/images/20201016/20125298hORdnGwp2h.png

C# Script call Java class

利用C# Script 的AndroidJavaObject呼叫
需要注意 Package Name跟function name就是前面使用Android studio定义的

 void Start()
    {
        javaClass = new AndroidJavaObject("Android's package name");
        javaClass.Call("Android function name","Hello Unity");
    }

https://ithelp.ithome.com.tw/upload/images/20201016/20125298Tk0SymcFBW.png

利用Adb shell 确认

在adb shell 中输入 logcat | grap JavaClass 可以看到前面写的logPrint确实有被呼叫了

https://ithelp.ithome.com.tw/upload/images/20201016/20125298LjR4J8nuss.png

加入自动更新

每次写一次就要移动资料夹确实是很麻烦,因此只要在Module下的那个gradle加入下面几行就可以自动把新build出来的Plugins import到Unity的路径。(记得先把Unity旧的Classes.jar删掉 因为这边有把他改名)

https://ithelp.ithome.com.tw/upload/images/20201016/20125298nZ0N1OFIiH.png

Import Unity Activity to Android Studio

因为许多的Android Native 元件都需要使用到Activity来创建,在这边要使用Unity的Activity来创造。
如下图 Unity的资料夹内找到classes.jar,复制到 Module路径下的libs
然後因为我们上面再grandle中有include('classes.jar'),Sync之後就会自动import了

https://ithelp.ithome.com.tw/upload/images/20201016/20125298VKRc3prF0W.png

Write toast function

接着就可以利用UnityPlayer.currentActivity来拿到Activity去创建Native的原件,这边写了两个Function,一个呼叫Toast,一个回传number+1的数字。

https://ithelp.ithome.com.tw/upload/images/20201016/201252988B27JPTJ9n.png

  public int getNumberPlus (int number)
    {
        return number+1;
    }
    public void showToast (String message)
    {

        Toast.makeText(UnityPlayer.currentActivity, "Toast "+message, Toast.LENGTH_SHORT).show();

    }

Unity 那边只需要使用AndroidJavaObject.Call即可以呼叫到前面写好的showToast以及getNumberPlus两个function

public class PluginWrapper : MonoBehaviour
{
    private AndroidJavaObject javaClass;

    public Text numText;
    public Button toastButton;

    


    // Start is called before the first frame update
    void Start()
    {
        javaClass = new AndroidJavaObject("com.example.unityplugin.JavaClass");
        javaClass.Call("logPrint","Hello Unity");
        numText.text = javaClass.Call<int>("getNumberPlus",100).ToString();
        toastButton.onClick.AddListener(new UnityEngine.Events.UnityAction (()=> showToast("Button Click")));
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void showToast(string message)
    {
        javaClass.Call("showToast", message);
    }
 

}

最後在Scene内新增一个Text和Button拉到PluginWrapper内Build出APK,按下按钮即可看到Toast。

https://ithelp.ithome.com.tw/upload/images/20201016/20125298B7mr9aMTaB.png


<<:  【修正模型】4-2 呼叫堆叠(Call Stack)

>>:  [JS] You Don't Know JavaScript [Scope & Closures] - The Module Pattern

Day 6 jinja (1)

前言 今天要来看 jinja 这个模板引擎。简单来说,它的功能就是在 HTML 里面执行一般程序,等...

[Day22] 网格交易机器人-报价接收

首先先在StockPrice以外,新增Bid和Ask,还有Lock(多线程读写资料避免打架的工具) ...

初浅认识Room

先前提过以SQLite 进行资料储存,但若是资料不但是有关连性,而且较多时候是局部更新,那麽使用Ro...

伸缩自如的Flask [day12] Sql Database

好的,这里来使用Sql的DataBase,我相信你已经知道或调查过了NoSql跟Sql两种Datab...

[Day_2] Python 资料型别与变数

资料型别 以下给大家介绍一些常用的资料型别,如下 : 符号 说明 False 布林值False 0 ...