モバイルにも対応した、Unity WebGL からツイートができるスクリプトを公開しました

はじめに

先日リリースした『ねねちーのお昼ご飯大作戦ある!』では、スクリーンショット付きで結果をツイートすることができます。

f:id:Gigacee:20201004223441p:plain
こんな感じ。

そしてこのたび、ここで使用したスクリプトを切り出して、GitHub にて公開いたしました。

github.com

デモはこちら。

www.gigacreation.jp

使い方

テキストのみツイートする

TweetFromUnityWebGL.jslib 内の TweetFromUnity() を実行することでツイートができます。以下のように呼び出してください。

using UnityEngine;
#if !UNITY_EDITOR && UNITY_WEBGL
using System.Runtime.InteropServices;
#endif

public class Demo1 : MonoBehaviour
{
#if !UNITY_EDITOR && UNITY_WEBGL
    [DllImport("__Internal")]
    private static extern string TweetFromUnity(string rawMessage);
#endif

    public void Tweet()
    {
#if !UNITY_EDITOR && UNITY_WEBGL
        TweetFromUnity("Tweet Message");
#endif
    }
}

PC 環境で実行するとブラウザで twitter.com の投稿画面が開かれ、モバイル環境だと Twitter アプリが起動します。

Sample1_Tweet シーンにこの例がありますので、ご参照ください。

スクリーンショット付きでツイートする

ゲームのスクリーンショット付きでツイートすることもできます。Imgur を使用した例を以下に示します。

Imgur のクライアント ID が必要です。取得手順はこちらを参照してください。

// Original code from https://github.com/ttyyamada/TweetWithScreenShotInWebGL
// Licensed under https://github.com/ttyyamada/TweetWithScreenShotInWebGL/blob/master/LICENSE

using System;
using System.Collections;
using System.Xml.Linq;
using UnityEngine;
using UnityEngine.Networking;
#if !UNITY_EDITOR && UNITY_WEBGL
using System.Runtime.InteropServices;
#endif

public class Demo2 : MonoBehaviour
{
    [SerializeField] private string _imgurClientId;

#if !UNITY_EDITOR && UNITY_WEBGL
    [DllImport("__Internal")]
    private static extern string TweetFromUnity(string rawMessage);
#endif

    public void TweetWithScreenshot()
    {
        StartCoroutine(TweetWithScreenshotCo());
    }

    private IEnumerator TweetWithScreenshotCo()
    {
        yield return new WaitForEndOfFrame();

        Texture2D tex = ScreenCapture.CaptureScreenshotAsTexture();

        var wwwForm = new WWWForm();
        wwwForm.AddField("image", Convert.ToBase64String(tex.EncodeToJPG()));
        wwwForm.AddField("type", "base64");

        // Upload to Imgur
        UnityWebRequest www = UnityWebRequest.Post("https://api.imgur.com/3/image.xml", wwwForm);
        www.SetRequestHeader("AUTHORIZATION", "Client-ID " + _imgurClientId);

        yield return www.SendWebRequest();

        var uri = "";

        if (!www.isNetworkError)
        {
            XDocument xDoc = XDocument.Parse(www.downloadHandler.text);
            uri = xDoc.Element("data")?.Element("link")?.Value;

            // Remove Ext
            uri = uri?.Remove(uri.Length - 4, 4);
        }

#if !UNITY_EDITOR && UNITY_WEBGL
        TweetFromUnity($"Tweet Message%0a{uri}");
#endif
    }
}

Sample2_TweetWithScreenshot シーンにこの例がありますので、ご参照ください。

なお、この Imgur を使用するコードは、やまださん制作のサンプルを参考にさせていただきました。ありがとうございます😊

特殊文字

改行やハッシュタグをツイート文に含めたい場合は、以下のようにしてください。

  • 改行 : %0a
  • ハッシュタグ (#) : %23

例:

TweetFromUnity("ツイートメッセージに、改行や%0aハッシュタグを含めることもできます!%0a%0a%23TweetFromUnityWebGL");

ツイートメッセージに、改行や
ハッシュタグを含めることもできます!

#TweetFromUnityWebGL

インストール

Package Manager

https://github.com/gigacee/TweetFromUnityWebGL.git?path=Assets/Plugins/TweetFromUnityWebGL

手動

Assets/Plugins/TweetFromUnityWebGL/TweetFromUnityWebGL.jslib を、自分のプロジェクトにコピーしてください。

※ 必ず Assets/Plugins/ に配置してください。でないと機能しません。

余談:このスクリプトができるまで

Unity WebGL からツイートするための方法は、ネットで調べるといくつかの情報がヒットします。ですがその多くが、すでに廃止されている Application.ExternalEval() を使用したもので、最新の Unity で動作するようなスクリプトは見つけることができませんでした。

とはいえ、Unity WebGL から JavaScript の関数を呼び出すこと自体は、前作の『かえちゃんジャンプ!!』でやったことがあります。その応用で、Unity 内で生成した文字列を JavaScript に渡し、twitter.com を開けばツイートできるのでは? と考え、最初に書いたコードが以下のようなものです。

// TweetFromUnityWebGL.jslib

mergeInto(LibraryManager.library, {
    TweetFromUnity: function (rawMessage) {
        var message = Pointer_stringify(rawMessage);
        window.open("https://twitter.com/intent/tweet?text=" + message, "_blank");
    },
});

Pointer_stringify() は、Unity 内の文字列を JavaScript 文字列に変換するためのものらしいです。

あとは Unity 内から TweetFromUnity("ツイート文だよ~") という感じで呼び出せば、 window.open(uri) で twitter.com の投稿画面が開き、ツイートができる! 完璧!! ……と思っていたのですが、iOS の Safari でゲームを実行すると、ポップアップブロック機能が働いてしまい、投稿画面が開いてくれませんでした。かと言って、 location.href = uri で遷移すると、ゲームを実行しているタブと同じタブで投稿画面が開いてしまい、ゲームが終了してしまいます。

どうしたものか……としばらく考え、モバイル端末なら大抵 Twitter アプリが入っているはずだから、そのアプリを直接起動すれば良いのでは??? と考えました。つまり、こんなコードです。

// TweetFromUnityWebGL.jslib

mergeInto(LibraryManager.library, {
    TweetFromUnity: function (rawMessage) {
        var message = Pointer_stringify(rawMessage);
        location.href = "twitter://post?message=" + message;
    },
});

モバイル環境で twitter://post?message= を実行すると、Twitter アプリが開きます。この URI (?) を調べるのに、だいぶ苦労しました……。

ですがこれだと、今度は PC でツイート画面が開けませんから、どうにかして実行環境が PC かモバイルかを判別しなくてはなりません。これに関してはネットに豊富な情報がありましたので、苦労せず実装することができました。

// TweetFromUnityWebGL.jslib

mergeInto(LibraryManager.library, {
    TweetFromUnity: function (rawMessage) {
        var message = Pointer_stringify(rawMessage);
        var mobilePattern = /Android|iPhone|iPad|iPod/i;

        if (window.navigator.userAgent.search(mobilePattern) !== -1) {
            // Mobile
            location.href = "twitter://post?message=" + message;
        } else {
            // PC
            window.open("https://twitter.com/intent/tweet?text=" + message, "_blank");
        }
    },
});

ユーザーエージェントを取得し、その中に「Android」「iPhone」「iPad」「iPod」のいずれかが含まれていたらモバイル端末、というように判別します。これで、すべての環境*1でツイートをすることができるようになりました!🎉 めでたしめでたし😊


追記(2020.10.18)

あとから知ったのですが、iOS 13.0 以降の iPad*2だと、ユーザーエージェントに「iPad」の文字列が入ってないんですね……。そのため、上記のコードだと iPad で Twitter アプリが開きません。iPad でも Twitter アプリが開くよう、以下のように修正しました。

// TweetFromUnityWebGL.jslib

<feff>mergeInto(LibraryManager.library, {
    TweetFromUnity: function (rawMessage) {
        var message = Pointer_stringify(rawMessage);
        var mobilePattern = /android|iphone|ipad|ipod/i;

        var ua = window.navigator.userAgent.toLowerCase();

        if (ua.search(mobilePattern) !== -1 || (ua.indexOf("macintosh") !== -1 && "ontouchend" in document)) {
            // Mobile
            location.href = "twitter://post?message=" + message;
        } else {
            // PC
            window.open("https://twitter.com/intent/tweet?text=" + message, "_blank");
        }
    },
});

ua.indexOf("macintosh") !== -1 で「Macintosh」の文字列を見つけ、なおかつ "ontouchend" in document でタッチ操作がサポートされているかを調べます。タッチ操作ができる Macintosh => iPad というわけですね。

なお、この PC かモバイルかを判別するスクリプトをさらに切り出したものを公開しているので、もしよければそちらもご覧になってください。

追記(2021.09.18)

Imgur のクライアント ID を取得する手順です。

  1. Imgur のアカウントを作成します。
  2. https://api.imgur.com/oauth2/addclient にアクセスします。
  3. 「Application name」に、任意のアプリ名(ゲームタイトルなど)を入力します。
  4. 「Authorization type」は、「Anonymous usage without user authorization」に設定します。
  5. 「Authorization callback URL」に、適当な URL を入力します。
    1. 特に使用しないので何でもいいです。自分は「https://imgur.com」を入力しました。
  6. 「Email」に、任意のメールアドレスを入力します。
    1. こちらも何でも大丈夫です。ユーザーに公開されたりすることもありません。
  7. 最後に、「submit」ボタンを押せば、クライアント ID を取得できます。

*1:モバイル端末で Twitter アプリがインストールされていない場合? そんなものは知らん🙄

*2:mini を除く。

The coloring of this site is Dracula PRO🧛🏻‍♂️
This website uses the FontAwesome icons licensed under CC BY 4.0.

2020 GIGA CREATION