Continue(s)

Twitter:@dn0t_ GitHub:@ogrew

【Unity】アプリからSNSへのシェア機能をつくる.

f:id:taiga006:20200130173247p:plain:w300

SNSシェア機能と仰々しく書きましたが、つまりはShare Extensionを表示させる方法です。 (ちなみにShare Extensionという用語はAndroid /iOSで共通なんでしょうか?まあどちらにせよ意味は通じると思いますが。)

ググってみるといくつか方法が出てきますが、今回はanchan828さんが公開しているSocical ConnectorをベースにTHE・車輪の再開発をしていきます。(プラグインをそのまま使う方法は他のサイトをご覧ください。)

シェア機能の本体となるスクリプトは以下のようになります。 パット見で分かる通りAndroidはUnityの機能のみで実装ができますが、iOSに関してはネイティブプラグインとして別途実装する必要があります。(後述)

using UnityEngine;

#if UNITY_IPHONE
using System.Runtime.InteropServices;
#endif

    public class SocialShare
    {
    public static void Share (string text, string url) {
#if UNITY_IPHONE
        _ShareiOS(text, url);
#elif UNITY_ANDROID
        _ShareAndroid(text, url);
#endif
    }

#if UNITY_IPHONE
        [DllImport ("__Internal")]
        private static extern void Social_Share (string text, string url);
        
        private static void _ShareiOS(string text, string url) {
            Social_Share(text, url);
        }
#elif UNITY_ANDROID
        private static void _ShareAndroid(string text, string url)
        {
            var clazz = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
            var activity = clazz.GetStatic<AndroidJavaObject> ("currentActivity");

            var intent = new AndroidJavaObject("android.content.Intent");
            intent.Call<AndroidJavaObject>("setAction", "android.intent.action.SEND");
            intent.Call<AndroidJavaObject>("setType", "text/plain");

            if (!string.IsNullOrEmpty(url))
                text += "\t" + url;

            if (!string.IsNullOrEmpty(text))
                intent.Call<AndroidJavaObject>("putExtra", "android.intent.extra.TEXT", text);

            var chooser = intent.CallStatic<AndroidJavaObject>("createChooser", intent, "");
            chooser.Call<AndroidJavaObject>("putExtra", "android.intent.extra.EXTRA_INITIAL_INTENTS", intent);
            activity.Call("startActivity", chooser);
        }
#endif
    }

今回はスクショは投稿しない形で実装したかったのでSocial Connectorからその部分の実装を削って、少し読みやすく整理しています。

ちなみに、スクショ付き機能が入るとAppleだと認証周りをいろいろ調整しないといけないのでちょっと話がややこしくなります。このあたりです。

最初にも書いたようにAndroidに関してはUnityからネイティブのメソッドを直接コールすることが可能です。

https://docs.unity3d.com/jp/460/Manual/PluginsForAndroid.html

そしてiOSプラグインの実装です。Asset下に適当なフォルダを作って(Pluginsとか)以下をSocialShare.mmという名前で保存します。

extern "C" {
    void Social_Share(const char *text, const char *url) {
        // MSStringに変換
        NSString *_text = [NSString stringWithUTF8String:text];
        NSString *_url  = [NSString stringWithUTF8String:url];
        
        NSArray *content = [NSArray arrayWithObjects:_text,_url,nil];

        UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:content applicationActivities:nil];
        [UnityGetGLViewController() presentViewController:activityView animated:YES completion:nil];
    }
}

Obj-C側で定義したのと同名の関数をC#側で static extern で定義させます。 C#のほうでそのメソッドを呼ぶと、プラグイン側のObj-Cの関数が呼ばれる。

Obj-Cのことがちんぷんかんぷんだったので、少しつまづきました。 (具体的にはarrayWithObjectsの最後にnilが必要だということがわかっておらず、ビルド後に無言クラッシュを食らってしまいしばし立ち往生しました。)

ここまで理解できたら、あとはシェアボタンなどから最初のスクリプトのメソッドを呼び出すようにすれば実装は完了です。お疲れさまでした。

    public void OnClickShareButton()
    {
        string shareText = "テストテストテスト";
        string shareUrl = "https://twitter.com/dn0t_";

        SocialShare.Share(shareText, shareUrl);
    }

f:id:taiga006:20200130173450j:plain:w300

さらにこれを応用させることで「Lv.100ステージクリア!!」「5000PT獲得!!」などのゲームない情報を気軽にユーザがシェアできるようになります。

今回はすでに広く使われているUnityプラグインを手元で再実装することで理解を深めるよい機会になりました。

参考

https://github.com/anchan828/social-connector

https://qiita.com/tkyaji/items/74d485a021c75ed10bca