Blogging for sharing, sekedar berbagi ilmu dan pengalaman

Membuat Native Android Plugin untuk Unity

July 09, 2014 Posted by Ahmad Saifuddin Azhar No comments

Unity Android

Unity merupakan game engine dimana game yang dihasilkan bersifat multi platform. Hasil output game engine ini dapat di porting ke dalam beberapa platform, mulai windows, Mac, iOS, Android, Windows Phone, dan masih banyak platform lainnya. Hal ini tentu sangat-sangat menguntungkan pengguna unity karena sekali develop game yang dihasilkan dapat dipublish ke dalam berbagai platform sesuai dengan keinginan.

Sayangnya, karena game yang dihasilkan sifatnya adalah multi platform maka tidak jarang ada fitur spesifik yang miss dan tidak dapat dibuat dengan Unity. Contoh untuk platform Android. Setahu saya Unity (sebelum dibuat plugin spesifik) tidak dapat digunakan untuk membuat fitur share, notifikasi, widget, background service, dsb. Saya belum banyak meng-explore tentang hal ini, barangkali kalau saya salah mohon dibenarkan.

Untungnya, Unity mengizinkan pemanggilan kelas native Android agar fitur-fitur tersebut dapat diintegrasikan bersama Unity.  Langkahnya kurang lebih kita buat terlebih dahulu Android plugin untuk unity, kemudian kita panggil plugin tersebut untuk menjalankan fungsi native Android.

Ok.. Langsung saja ke intinya.. Pada artikel kali ini saya akan mencoba menjelaskan sedikit tentang cara membuat Android plugin untuk Unity. Sebelum memulai kita lihat dulu apa saja alat dan bahanya :
1. Unity, pada tutorial ini saya memakai unity 4.5.1. Uniti dapat di download disini.
2. Eclipse ADT (Android Developer Tools). Merupakan modifikasi dari eclipse IDE. ADT dapat di download di situs resmi Android developer disini.
3. Android SDK, biasanya satu paket saat mendownload ADT. 
4. Device Android. Kalau tidak ada bisa menggunakan Android emulator

Setelah alat dan bahan siap langsung saja ke stepnya...

Note : Bagi yang ingin mendownload projectnya terlebih dahulu sebagai bahan belajar klik disini

Langkah 1. Buat Unity project untuk platform Android
langkah pertama buat unity project. Kemudian switch platformnya ke platfrm android. Untuk switch platform klik file >> build settings

Switch platform unity  android

Tentukan bundle identifier pada player setting. Lihat gambar

Player setting unity android

Langkah 2. Buat Android Project
Untuk membuat Android plugin kita buat dulu Android project. Caranya buka Eclipse ADT kemudian buat project Android baru seperti pada gambar di bawah

Membuat project android untuk plugin unity

Kita tentukan nama aplikasinya. Untuk nama packagenya usahakan sama dengan nama package pada langkah 1. 

Konfigurasi project android

Tentukan lokasi project. Buat 1 activity hanya untuk contoh, agar kita bisa memastikan aplikasi kita dapat berjalan sebelum di-include ke unity.

Menentukan lokasi project android

 Untuk membuat activity cukup next-next aja. Ikuti seperti gambar di bawah.


memberi nama activity

Selanjutnya kita akan mencoba native plugin ini dengan mencobanya ke device. Colokkan perangkat Android Anda di komputer. Atau Anda dapat menjalankan emulator. Buka DDMS dan pastikan koneksi PC - Device sudah berhasil.

Deteksi device pada DDMS

Kemudian run aja. Tekan button 'run' pada bar atas. Lihat statusnya pada console.

Status run android

Tunggu beberapa saat, jika eksekusi berhasil seharusnya di devica Anda akan muncul tampilan seperti pada gambar di bawah.

Langkah 4. Buat Android plugin untuk Unity
Langkah selanjutnya kita akan membuat plugin yang bisa dipanggil di Unity. Pertama buat kelas NativeAndroidBridge.java. 

Membuat kelas untuk plugin unity

adapun isi dari kelas tersebut adalah sbb :

NativeAndroidBridge.java
package com.duniadigit.androidplugin;

public class NativeAndroidBridge{
 private static int number = 0;
 
 public static int getNumber(){
  number += 1;
  return number;
 }
}

Kemudian kita atur properti project menjadi library. Hal ini karena memang project ini nantinya hanya dijadikan library tambahan untuk Unity. Stepnya seperti pada gambar di bawah :

Pertama klik kanan project >> properties

Mengganti properti project

Pada bagian Android >> klik Is Library

Centant IsLibrary karena dibuat plugin

Kemudian lihar pada folder bin. Maka ada androidplugin.jar

Plugin android dengan ekstensi .jar

Langkah 5. Import dan buat kelas Bridge di unity
Kemudian langkah selanjutnya  kita import ke unity. Buat folder /Plugins/Android. Kita drag & drop file androidplugin.jar tadi ke folder ini.

Note : Folder jangan dirubah. Selalu paka folder /Plugins/Android

Import plugin android ke unity


Kemudian buat kelas yang menjadi jembatan antara android plugin dengan unity. Disini saya membuat kelas NativeAndroidBrige.cs

Kelas bridge untuk komunikasi dengan plugin android

Adapun isi dari kelas ini adalah sbb :

using UnityEngine;
using System.Collections;

public class NativeAndroidBridge : MonoBehaviour {
 public static int GetNumber(){
  int number = 0;

  if(Application.platform == RuntimePlatform.Android){
   AndroidJavaClass androidJavaClass = new AndroidJavaClass("com.duniadigit.androidplugin.NativeAndroidBridge");
   number = androidJavaClass.CallStatic("getNumber");
  }

  return number;
 }
}

Langkah 6. Test
Langkah selanjutnya adalah melakukan test apakah plugin ini berjalan dengan baik atau tidak. Untuk melakukannya saya buat kelas tambahan. Saya beri nama GameGUI.cs

Kelas GUI untuk test plugin android


Adapun isi dari GameGUI adalah sbb :

using UnityEngine;
using System.Collections;

public class GameGUI : MonoBehaviour {
 private int number;

 void OnGUI(){
  GUI.Box(new Rect(0,0,Screen.width, 25), number.ToString());
  bool isButtonPressed = GUI.Button(new Rect(0,30,100,25), "Get Number");
  if(isButtonPressed){
   number = NativeAndroidBridge.GetNumber();
  }
 }
}

Implementasikan eklas tersebut ke dalam scene. Pada contoh ini saya meletakkan script ini ke object camera.

Meletakkan kelas GUI ke dalam scene

Karena plugin ini hanya berjalan di Android, maka kembali colokkan device Anda ke PC. Kemudian klik file >> build & run atau ctrl+B. Hasilnya adalah sbb :

Test plugin android unity

KESIMPULAN
Tutorial ini adalah tutorial sederhana membuat plugin Android untuk Unity. Pada tutorial ini plugin akan memberikan result balik berupa angka. Sedangkan unity hanya bertugas meminta angka tersebut kepada plugin.


Ok... sekian artikel yang dapat saya sampaikan. Terima kasih telah membaca. Semoga bermanfaat dan   terus berkarya ^^

Download link project klik disini



[OOP] Sekilas Tentang Fungsi Interface di Java, C#, dan Bahasa Pemrograman OOP Lainnya

July 09, 2014 Posted by Ahmad Saifuddin Azhar 7 comments
Hampir semua bahasa pemrogramaan berbasis OOP menyediakan fasilitas Interface, sebut saja yang cukup terkenal seperti Java dan C#. Mungkin Sobat programmer sedikit banyak sudah sangat hafal apa itu pengertian interface, yaitu suatu kelas yang memiliki deklarasi method tanpa adanya implementasi di dalamnya. Namun hafal pengertiannya saja tidak cukup bukan? Faktanya, dari sebagian besar sahabat programmer yang saya temui masih cukup banyak yang bingung tentang apa itu interface dan apa fungsinya. Padahal adanya interface ini menurut saya sangat-sangat penting. Nah pada artikel ini akan saya uraikan secara singkat apa saja manfaat interface dengan sedikit contoh kasus sederhana sbb :

Note : Sebelum melihat lebih jauh Anda dapat mendownload contoh projectnya disni.

Contoh kasus :
Misal saya ingin membuat game balap mobil. Tahu kan game balap mobil?  Jadi kurang lebih seperti ini nih game yang pengen saya buat 

Game mobil balap

Kemudian pengennya abis game mobil ini selesai saya mau bikin game balapan boat. Jadi kayak gini nih contohnya 

Game balap Boat

Masalahnya nih... Saya itu orangnya super males... Saya gak mau bikin program berkali-kali, saya maunya bikin code 1x doank, nanti kalo ada tambahan ya ditambahi, tapi saya gak mau ngoding sesuatu yang hampir sama 2x, gak efisien.
  
Nah.. akhirnya untuk kasus ini saya memecah program menjadi tiga kelas utama. Perkara kelas ini nanti extends ke macem-macem g masalah, yang penting saya mau bahas ketiga kelas utama ini. Kelas-kelas itu antara lain :
1. Kelas HUD (Head Up Display). Apa itu HUD? Bisa baca lebih detail di wikipedia. Intinya gini.. ibarat sebuah mobil, kelas ini adalah kelas untuk kemudi dan segala peralatan navigasinya. Kelas ini berfungsi untuk menangani input user seperti setir kanan dan kiri, gas, rem, menampilkan status kecepatan, nitro, posisi, lap, mini map, dsb. Intinya kelas ini menangani antarmuka kendaraan dengan user atau bisa dikatakan navigasi.

Tentang HUD (Head Up Display)

Karena saya itu males, saya pengennya kelas ini dipake 2x, pada proyek pertama saya akan menggunakan kelas ini untuk mengontrol mobil, tapi pada proyek kedua saya akan menggunakannya kembali untuk mengontrol boat, dimana mobil dan boat jelas-jelas berbeda, engine nya juga jelas jauh berbeda.
2. Kelas Car. Sesuai namanya, kelas ini adalah kelas untuk menjalankan mobil. Ibaratnya kelas ini adalah mesin dari mobil.
3. Kelas Boat. Sama seperti kelas mobil, kelas ini bisa diibaratkan dengan sebagai mesin dari boat. 

Kemudian gimana caranya, bikin dua kelas berbeda tapi bisa di kontrol oleh satu HUD? Inilah salah satu fungsi dari interface. Ok.. Langsung saja kita bahas lebih detail tentang fungsi dari interface. Berikut adalah beberapa fungsi dari interface :

FUNGSI 1 : Membuat program lebih reuseable. Menurut saya inilah fungsi utama interface. Dengan memanfaatkan interface setiap bagian program dapat dijadikan suatu modul tersendiri. Modul ini dapat diberi interface tertentu sehingga untuk memanfaatkan modul ini pada proyek lain cukup dengan mengimplementasikan interface yang telah disediakan, sehingga tidak perlu merubah code program sedikitpun. Cukup implementasi, beres.. 

Contoh kasus : 
Dari contoh kasus di atas jelas kan, kita pengen memakai 1 HUD untuk mengontrol lebih dari satu type kendaraan yang sangat berbeda. Bahkan bisa jadi pada proyek berikutnya muncul kelas-kelas baru seperti tank, train, truck, dsb. Kelas-kelas ini bisa sangat rumit, bisa extends ke kelas apapun. 

Tentu akan memakan waktu cukup lama kan jika kita membuat 1 kelas HUD untuk 1 type kendaraan? Bukannya lebih baik kita buat 1 HUD untuk semua kendaraan? Kalaupun texturenya beda-beda (misal bentuk kemudi mobil dan kemudi truck beda) kan itu cuman beda texture saja, bisa diganti dengan mengganti atribut texture dari kelas HUD saja, tidak perlu menambah kelas HUD baru karena intinya fungsi dari HUD itu sama, untuk mengontrol kendaraan, entah itu kendaraan darat, air, bahkan udara. Kalaupun nanti ada fungsi tambahan, misal tank tambah fungsi Shot, bisa kita extends dari kelas HUD, tp intinya ya tetap 1 HUD untuk semua vehicle. Kemudian gimana cara kita untuk memodelkannya?

Untuk itulah kita perlu interface yang menyeragamkan semua type kendaraan yang berbeda itu agar bisa di kontrol oleh HUD. Kita bisa buat interface ControllableVehicle atau jika saya pribadi saya lebih senang menambahkan huruf 'I' di awal nama interface untuk membedakan namanya dengan kelas. Jadi namanya menjadi IControllableVehicle. Nah interface inilah yang nanti bisa diimplementasikan oleh kelas-kelas yang bisa dikontrol oleh HUD. Jadi intinya HUD tidak mengenal apa itu mobil, boat, train, tank, dsb. Yang HUD tahu adalah HUD dapat mengontrol interface IControllableVehicle. Jadi kalo kita pengen menambah apapun yang bisa di kontrol HUD apakah itu truck, tank, train, motor cycle, kuda, sapi, onta, singa, keong, ubur-ubur, kecoak, semut, amoeba, kuman, virus apapun itu cukup mengimplementasikan interface IControllableVehicle. Beres...

Dengan cara ini kelas HUD menjadi sangat reuseable bukan?? 1x develop bisa buat control apapun. Kelas car, boat, dsb juga menjadi reuseable. Kenapa? Karena mereka bersifat independent. Mereka mengimplementasikan IControllableVehicle. Bisa jadi kelas-kelas ini kita buat untuk platform PC, android, iOS, Play Station, Xbox, dll. Diantara platform ini jelas memiliki HUD yang jauh berbeda, karena PC mengandalkan keyboard sebagai input, android dan iOS mengandalkan touch screen, Play Station mengandalkan Joystick. Jelas sangat jauh beda kan HUD diantara platform-platform ini? Tapi HUD yang beda-beda ini bisa kita seragamkan untuk mengontrol interface yang sama, yaitu IControllableVehicle. Nah loh... 1x develop uda bisa dipakai dimana aja, plus buat project beda-beda kan?? Inilah kekuatan OOP, cukup sakti jika kita bisa memanfaatkan fitur-fiturnya.. :)

Dan berikut adalah contoh scriptnya. Saya buat menggunakan java karena saya rasa java lebih familiar dengan Sobat programmer :

Kelas HUD.java
public class HUD {

    private final IControllableVehicle vehicle;

    public static void main(String[] args) {
        System.out.println("Start to controll Car");
        HUD hudCar = new HUD(new Car());
        hudCar.drive();

        System.out.println("Start to controll Boat");
        HUD hudBoat = new HUD(new Boat());
        hudBoat.drive();
    }

    public HUD(IControllableVehicle vehicleToControl) {
        this.vehicle = vehicleToControl;
    }

    private void drive() {
        vehicle.accelerate();
        vehicle.turnLeft();
        vehicle.turnRight();
        vehicle.brake();
    }
}

Interface IControllableVehicle.java
public interface IControllableVehicle {
    void accelerate();
    void brake();
    void turnLeft();
    void turnRight();
}

Kelas Car.java
public class Car implements IControllableVehicle {

    @Override
    public void accelerate() {
        System.out.println("Car accelerate");
    }

    @Override
    public void brake() {
        System.out.println("Car brake");
    }

    @Override
    public void turnLeft() {
        System.out.println("Car turn left");
    }

    @Override
    public void turnRight() {
        System.out.println("Car turn right");
    }
}

Kelas Boat.java
public class Boat implements IControllableVehicle {

    @Override
    public void accelerate() {
        System.out.println("Boat accelerate");
    }

    @Override
    public void brake() {
        System.out.println("Boat brake");
    }

    @Override
    public void turnLeft() {
        System.out.println("Boat turn left");
    }

    @Override
    public void turnRight() {
        System.out.println("Boat turn right");
    }
}
  
Adapun output yang ditampilkan adalah sbb :

Fungsi interface membuat program lebih reuseable

Sekarang jelas bukan? Pada contoh diatas hanya ada 1 kelas HUD. Namun kelas HUD ini dapat digunakna untuk melakukan control beberapa kelas yang berbeda, dengan catatan kelas tersebut harus mengimplementasikan IControllableVehicle. Sangat efisien bukan?



FUNGSI 2 : Menangani event. Interface dapat juga digunakan untuk menangani suatu event tertentu dari suatu kelas. Mungkins sedikit saja penjelasannya, langsung masuk ke contoh kasusnya 

Contoh kasus :
Masih dengan kasus bikin game racing tadi. Kita akan menambah 1 kelas lagi yaitu pemadam kebakaran atau kita sebut Fireman. Ceritanya, Fireman ini bertugas memadamkan object yang terbakar, entah itu Mobil atau Boat.

Satu poin penting disini, object vehicle dalam hal ini Car dan Boat adalah object utama yang menjadi pusat perhatian Fireman. Sedangkan Fireman hanya Object tambahan sebagai pelengkap. Intinya, tanpa Fireman Mobil atau Boat dapat berjalan dan tidak ada masalah. Namun Fireman tanpa Mobil atau Boat tidak bekerja karena tidak tahu apa yang diawasi. Poin penting berikutnya dalam hal ini adalah adanya sebuah event, yaitu ketika mobil terbakar, atau dapat kita sebut OnBurn event.

Dalam logika kita sebagai manusia, seorang Fireman akan selalu memantau Car setiap detik bahkan setiap milisecond. Ketika mobil meledak maka Fireman akan langsung berlari mendatangi mobil untuk memadamkan. Kita dapat membuat hal tersebut di dalam program sbb :

Kelas Car.java
public class Car implements IControllableVehicle {
    boolean isCarBurn;
    
    public boolean  isBurn(){
        return this.isCarBurn;
    }

    //Method lain-lain
}

Kelas Fireman.java
public class Fireman {
    Car car;
    
    //Fungsi ini dipanggil setiap 0.2 detik
    void Update(){
        if(car.isBurn()){
            //Mendatangi mobil dan memadamkan api
        }
    }
}

Namun pertanyaanya? Seberapa efisienkah cara ini? Bagaimana jika Fireman harus mengamati 10.000 mobil sekaligus? Tentu hal ini akan sangat membebani kerja CPU.

Salusi kedua yang lebih efisien adalah sebelum permainan dimulai kita beri tahu mobil, kalau-kalau terjadi kebakaran maka segera hubungi Fireman. Jadi ketika sewaktu waktu ada event burn, maka mobil akan segera menghubungi Fireman. Ini akan jauh-jauh lebih efisien karena fireman tidak harus selalu melihat mobil setiap detik, namun mobil apa saja yang terbakar akan segera menghubungi Fireman untuk dipadamkan.

Nah untuk membuatnya kita akan membuat interface dapat terbakar yang kita sebut IBurnable. Berikut adalah kelas Fireman, Car, dan interface IBurnable. Untuk mempermudah saya akan memodifikasi kelas mobil dengan memberinya nama.

Interface IBurnable.java
public interface IBurnable {
    void burn();
    void registerFireman(Fireman fireman);
    void removeFireman(Fireman fireman);
}


Kelas Fireman.java
public class Fireman {
    String name;
    ArrayList firemans = new ArrayList 
 
    public Fireman(String name) {
        this.name = name;
    }
    
    public void AnObjectIsOnFire(IBurnable burnable){
        System.out.println(name + " goto : " + burnable.toString());
    }
}

Kelas Car.java
public class Car implements IControllableVehicle, IBurnable {
    String name;
    
    public Car() { }
    
    public Car(String name) { 
        this.name = name;
    }
    
    @Override
    public void accelerate() {
        System.out.println("Car accelerate");
    }

    @Override
    public void brake() {
        System.out.println("Car brake");
    }

    @Override
    public void turnLeft() {
        System.out.println("Car turn left");
    }

    @Override
    public void turnRight() {
        System.out.println("Car turn right");
        burn(); //simulasi misal ketika belok kanan mobil akan terbakar
    }

    @Override
    public void burn() {
        for(Fireman fireman : firemans){
            fireman.AnObjectIsOnFire(this);
        }
    }

    @Override
    public void registerFireman(Fireman fireman) {
        if(!firemans.contains(fireman)){
            firemans.add(fireman);
        }
    }

    @Override
    public void removeFireman(Fireman fireman) {
        if(firemans.contains(fireman)){
            firemans.remove(fireman);
        }
    }

    @Override
    public String toString() {
        return this.name;
    }
}
 
Dalam kelas diatas lihat kelas mobil dalam method turnRight. Pada method tersebut kita asumsikan jika mobil belok ke kanan, maka mobil akan terbakar. Hal ini cuma digunakan untuk test program. Selain itu kita asumsikan ketika mobil meledak player akan berganti mobil dan mengendarai mobil lainya. Berikut adalah script HUD nya :

Kelas HUD.java
public class HUD {

    private final IControllableVehicle vehicle;

    public static void main(String[] args) {       
       //Create fireman
       Fireman paijo = new Fireman("Paijo");
       Fireman paimin = new Fireman("Paimin");
       Fireman santoso = new Fireman("Santoso");
       
       //Create car
       Car ferrari = new Car("Ferrari");
       Car toyota = new Car("Toyota");
       
       //Register fireman
       ferrari.registerFireman(paijo);
       toyota.registerFireman(paimin);
       toyota.registerFireman(santoso);
       
       
       //Test
       HUD hud = new HUD(ferrari);
       hud.drive();
       System.out.println("");
       hud = new HUD(toyota);
       hud.drive();
    }

    public HUD(IControllableVehicle vehicleToControl) {
        this.vehicle = vehicleToControl;
    }

    private void drive() {
        vehicle.accelerate();
        vehicle.turnLeft();
        vehicle.brake();
        vehicle.turnRight();
    }
}

Adapun outputnya adalah sbb :

Fungsi Interface untuk menangani event

Nah dalam HUD tadi dapat kita garis bawahi sbb :
1. Terdapat 3 orang fireman : Paijo, Paimin, dan Santoso.
2. Terdapat 2 buah mobil : Ferrari dan Toyota
3. Mobil Ferrari diawasi oleh Paijo, sedangkan Toyota diawasi oleh Paimin dan Santoso.
4. Ketika terjadi event burn dari mobil, maka mobil akan melaporkan event tersebut terhadap listenernya.

KESIMPULAN :
Interface merupakan satu bagian penting dari sebuah bahasa pemrograman OOP. Mungkin suatu program dapat berjalan dengan baik tanpa menggunakan interface. Namun, penggunaan fungsi interface dapat membuat program lebih flexible dan mudah dikembangkan. Penggunaan interface juga dapat membuat program menjadi lebih efisien karena Interface dapat digunakan untuk menangani event tertentu dalam suatu object.  

PENUTUP :
Ok.. Penjelasan tadi adalah sedikit fungsi dari interface yang mungkin sering digunakan.  Semoga artikel ini bermanfaat sehingga Sobat dapat menggunakan fungsi Interface dengan baik. Mungkin sekian yang dapat saya sampaikan.  Untuk download contohnya saya sertakan di link bawah. Tetap semangat dan terus berkarya... ^^

Link download contoh klik disini (netbeans project)