ساخت پلاگین یونیتی برای لایبرری اندرویدی

Android and Unity (Image taken from android.jlelse.eu)
Android and Unity (Image taken from android.jlelse.eu)

ما یه کتابخونه واسه‌ی اندروید (زبان جاوا یا کاتلین و مختص اندروید استودیو) طراحی کردیم، اما می‌خواستیم که بازی‌سازهایی که با موتور بازی‌سازی یونیتی بازی‌هاشونو طراحی می‌کنن هم بتونن از کتابخونمون استفاده کنن. پس بر این شدیم که برای یونیتی یه پلاگین طراحی کنیم که بازی‌ساز‌ها بتونن از این پلاگین تو بازی‌هاشون استفاده کنن و امکانات کتابخونه‌ی ما براشون فراهم باشه. توی این پست من در مورد نحوه‌ی ساخت پلاگین یونیتی برای کتابخونه‌ای که برای اندروید استودیو هست، توضیحاتی می‌دم.

۱. آماده‌سازی کتابخانه‌ی اندروید

این که چجوری لایبرری برای اندروید استودیو بسازیم جزو مطالب این پست نیست و فرض بر این می‌گیریم که کتابخونه آماده‌ست و یا در ‌Jcenter آپلود شده. می‌تونید از آموزش آپلود لایبرری در Bintray در موردش بخونید.

۲. اضافه‌کردن کتابخانه به یک پروژه‌ی یونیتی

حالا یه پروژه‌ی یونیتی خالی می‌سازیم و کارای لازم لایبرری رو توی این پروژه انجام می‌دیم. ابتدا یه پروژه بسازید و پلتفرم اندروید رو انتخاب کنید.

انتخاب پلتفرم اندروید
انتخاب پلتفرم اندروید

بعدش برای اینکه بتونید کتابخونه‌ی نیتیو اندرویدتون رو اضافه کنید از ابزار UnityJarResolver استفاده‌کنید. نسخه‌ی نهایی پکیج رو دانلود کنید و اونو توی پروژه اضافه کنید.

برای اضافه‌کردن پکیج می‌تونید در حالی که پروژه بازه پکیج رو باز کنید تا به پروژه اضافه بشه، یا با راست کلیک روی Assets و انتخاب گزینه‌ی Import > Custom package پکیج رو انتخاب کنید.


پس از اینکه پکیج اضافه شد برای آماده‌سازی بستر پلاگین توی پوشه‌ی Assets یک پوشه به اسم پلاگین بسازید و داخل اون یک پوشه به اسم Editor.

داخل پوشه‌ی Editor یک فایل به اسم Plugin+Dependencies.xml بسازید. مثلا اگه اسم پلاگینتون MyPluginـه یه فایل به اسم MyPluginDependencies.xml بسازید. شمای Assets به صورت زیر خواهدشد:

Assets/
    MyPlugin/
            Editor/
                        MyPluginDependencies.xml

توی فایل xml لایبرری‌هایی که قراره دانلود بشن و به پروژه اضافه بشن رو تعریف می‌کنیم. برای نمونه می‌تونید فایل مثال Unity jar resolver رو ببینید.

برای مثال کتابخونه‌ی پوشه رو به برنامه اضافه می‌کنیم. محتوای فایل xml بصورت زیر خواهد بود:

<dependencies>
  <androidPackages>
      <androidPackage spec=&quotco.ronash.android:pushe-base:1.6.3&quot>
            <repositories>
                    <repository>https://maven.google.com</repository>
           </repositories>
    </androidPackage>
  </androidPackages>
</dependencies>

برای حالت‌های بیشتر کامنت‌های فایل مثال رو بخونید.

فایل رو ذخیره کنید و برگردید به یونیتی. از منوی Assets گزینه‌ی Play service resolver، بعد Android resolver و بعد گزینه‌ی Force resolve یا resolve رو انتخاب کنید (با توجه به تحریم‌بودن سرور‌های گریدل باید از ابزار گذر از تحریم استفاده کنید).

بعد از سینک (در صورت دانلود موفق ابزار‌های لازم) در پروژه پوشه‌ی Plugin > Android به Assets اضافه خواهد شد. این یعنی کد نیتیو لایبرری شما + تمام لایبرری‌های مورد نیاز اون به برنامه اضافه‌شده و کدها قابل استفاده هستن.

تا اینجا Hirarchy پروژه باید بصورت زیر باشه:

۳. ساخت اسکریپت برای ساده‌کردن استفاده‌ی توسعه‌دهنده‌ها

برای استفاده از کدهای لایبرری در اسکریپت‌های یونیتی باید از کلاس‌های AndroidJavaClass و AndroidJavaObject استفاده کنیم. اما این کار برای توسعه‌دهنده‌های بازی که غالبا آشنایی با این کار ندارن خیلی خوشایند نیست. پس بهتره واسطی بسازیم که استفاده از کد‌های ما راحت و جذاب باشه و خیلی دورازذهن بازی‌ساز نباشه.


پس یک اسکریپت می‌نویسیم که توابعی داره و اون توابع کار اجرای کد‌های لایبرری رو بعهده می‌گیرن.

[ترجیحا توی پوشه‌ی پلاگین، یه‌جایی] یه اسکریپت سی‌شارپ بسازید و کد‌های زیر رو قراربدید (با توجه به اینکه ما لایبرری پوشه رو اضافه‌کردیم کد‌های اون رو استفاده خواهیم‌کرد):


public class Pushe : MonoBehaviour
    {
        private void Start()
        {
            try { InitializePushe(); }
            catch { Debug.Log(&quotFailed to initialize the project somehow!&quot); }
        }
        
        private static void InitializePushe()
        {
          var activityClass = new AndroidJavaClass(&quotcom.unity3d.player.UnityPlayer&quot); // ۱
          var activityContext = activityClass.GetStatic<AndroidJavaObject>(&quotcurrentActivity&quot);//۲
          var pluginClass = new AndroidJavaClass(&quotco.ronash.pushe.Pushe&quot);//۳
            pluginClass.CallStatic(&quotinitialize&quot, activityContext, /* show dialog */true);//۴
        }
}

در کد جاوا برای init شدن لایبرری باید کد

co.ronash.pushe.Pushe.initialize(context, true)

اجرا بشه. یک تابع میسازیم به اسم InitializePushe و کدهای لازم رو اجرا می‌کنیم:

  1. برای گرفتن ‌رفرنس کلاس اصلی یونیتی (UnityPlayer).
  2. برای گرفتن context اکتیویتی از کلاس اصلی یونیتی.

کدهایی که Context لازم دارن، آرگومان لازم رو از انجام موارد ۱ و ۲ می‌گیریم.

۳. رفرنس کلاسی که می‌خوایم ازش شی‌ بسازیم و تابعی ازش اجرا کنیم رو می‌گیریم.

۴. فراخوانی تابعی که لازم داریم اجرا بشه.

برای فراخوانی متد‌های استاتیک:

var pluginClass = new AndroidJavaClass(&quotClass_full_packageName&quot);
pluginClass.CallStatic<type>(&quotfunction_name&quot, args...); // no <type> if void

و فراخوانی با ساخت شی از کلاس:

AndroidJavaObject obj = new AndroidJavaObject(&quotClass_full_packageName&quot);
Type t = obj.Call<type>(&quotfunction_name&quot); // No <type> if void

به طور کلی روش فراخونی کد و تعامل با کد نیتیو کتابخونه‌ها اینطوری خواهد بود.


پس کسی که از پلاگین استفاده کنه به جای فراخونی دستی کد‌های نیتیو، کافیه از توابعی که آماده‌شده استفاده کنه:

var activityClass = new AndroidJavaClass(&quotcom.unity3d.player.UnityPlayer&quot);
var activityContext = activityClass.GetStatic<AndroidJavaObject>(&quotcurrentActivity&quot);
var pluginClass = new AndroidJavaClass(&quotco.ronash.pushe.Pushe&quot);
pluginClass.CallStatic(&quotinitialize&quot, activityContext, /* show dialog */true);

To:

InitializePushe();


حالا کافیه اسکریپتی که نوشتیم تسط توسعه‌دهنده به یک GameObject متصل بشه وکدهاش فراخوانی بشن. در این صورت کد‌هایی که ما در لایبرری نیتیو نوشتیم فراخوانی خواهندشد.


لینک پروژه‌ی نمونه

ابزار اضافه‌کردن dependency library به پروژه