Unity Native Pluginの作り方(共通編)


概要

iOSやAndroid向けに開発したSDKをUnityアプリに対応させる場合、プラグインを作ってSDKとUnityアプリの橋渡しをしてやる必要があります。本記事ではUnity側からSDKにアクセスするためのコードの一例を紹介します。具体的なプラグインの実装部分については、それぞれiOS編Android編を参考にして下さい。

サンプルコード

ISample.cs

Unity側からSDKのコードにアクセスするためのメソッドを宣言するインタフェースです。このインタフェースの実装についてはそれぞれiOS編Android編を参考にして下さい

ISample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum SampleStatus {
    Unavailable = 0,
    Available = 1
}

public interface ISample {
    void Start(string sampleCode);
    void DoSomething();
    SampleStatus GetStatus();
    int GetScore();
    bool IsAvailable();
    string GetSomeText();
}

Sample.cs

上記インタフェースを実装したオブジェクトをsampleNativeとして保持し、そのメソッドの呼び出しを代理で行うWrapperクラスです。

Sample.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using MiniJSON;

public class Sample : MonoBehaviour {
    private ISample sampleNative;
    public string iosSampleCode;
    public string androidSampleCode;
    private static Sample instance;

    public static Sample GetInstance() {
        if (instance == null) {
            Sample existingInstance = GameObject.FindObjectOfType<Sample>();

            if (existingInstance == null) {
                return null;
            }

            existingInstance.SetSampleNative();
            instance = existingInstance;
        }

        return instance;
    }

    private void Awake() {
        if (instance != null) {
            GameObject.Destroy(this);
            GameObject.Destroy(this.gameObject);
            return;
        }

        SetSampleNative();
        GameObject.DontDestroyOnLoad(this.gameObject);

        instance = this;
    }

    private void SetSampleNative() {
        if (sampleNative != null) {
            return;
        }

        #if UNITY_IOS
            sampleNative = new Sample_iOS(this);
        #elif UNITY_ANDROID
            sampleNative = new Sample_Android(this);
        #endif
    }

    public void DoSomething() {
        sampleNative.DoSomething();
    }

    public SampleStatus GetStatus() {
        return sampleNative.GetStatus();
    }

    public int GetScore() {
        return sampleNative.GetScore();
    }

    public bool IsAvailable() {
        return sampleNative.IsAvailable();
    }

    public string GetSomeText() {
        return sampleNative.GetSomeText();
    }

    public ISample SampleNative {
        get {
            return sampleNative;
        }
    }
}

SampleEventListener.cs

SDKからのコールバックをUnity側で受けるためのListenerクラスです。

SampleEventListener.cs
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using MiniJSON;

public class SampleEventListener : MonoBehaviour {
    public static event Action<SampleStatus> NotifyStatusChanged;
    private ISample nativeParent;

    public void SetNativeParent(ISample nativeParent) {
        this.nativeParent = nativeParent;
    }

    public void _Sample_didStatusChange(string message) {
        SampleStatus status = (SampleStatus)int.Parse(message);

        if (NotifyStatusChanged != null) {
            NotifyStatusChanged(status);
        }
    }
}

使用例

Main.csを任意のSceneにアタッチすることでSampleオブジェクトの初期化が行われ、以降はSampleオブジェクト経由でSDKの機能にアクセスすることが可能になります。

Main.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour {
    void Start () {
        Sample.GetInstance();
    }

    public void OnClickDoSomething() {
        Sample.GetInstance().DoSomething();
    }

    public void OnClickGetStatus() {
        SampleStatus status = Sample.GetInstance().GetStatus();
        ToastUtil.Toast(this, "Status: " + status);
    }

    public void OnClickGetSomeText() {
        string text = Sample.GetInstance().GetSomeText();
        ToastUtil.Toast(this, "text: " + text);
    }

    void OnEnable() {
        SampleEventListener.NotifyStatusChanged += NotifyStatusChanged;
    }

    void OnDisable() {
        SampleEventListener.NotifyStatusChanged -= NotifyStatusChanged;
    }

    private void NotifyStatusChanged(SampleStatus status) {
        Debug.Log("# Status changed: " + status);
    }
}

参考