Twitterでゲームのスクショを共有する処理を作った時にハマった話


前置き

  • twitterでスクショを共有する処理を作ろうとした
  • 対応ビルドは iOS/Android/WebGL の3つにした
  • キャプチャ画像のアップロード先は Imgur を使用することにした
  • なのでImgurのAPIを使用してUnityからhttpリクエストしてアップロードすることにした
  • Unityは 2018.4.12f1
  • 大きく3つの問題にぶつかった

作ってみました

ハマった話

card表示がアップロードした画像の直URLだと表示されない

事象

APIのレスポンスがアップロードした画像の直URLなので、そのURLをそのまま利用したがcard表示されなかった

responseはこんな感じ
<?xml version="1.0" encoding="utf-8"?>
<data type="array" success="1" status="200">
  <id>xxxxx</id><title/><description/><datetime>1574052543</datetime><type>image/png</type><animated>false</animated><width>1082</width><height>646</height><size>34163</size><views>0</views><bandwidth>0</bandwidth><vote/><favorite>false</favorite><nsfw/><section/><account_url/><account_id>0</account_id><is_ad>false</is_ad><in_most_viral>false</in_most_viral><has_sound>false</has_sound><tags/><ad_type>0</ad_type><ad_url/><edited>0</edited><in_gallery>false</in_gallery><deletehash>yyyyy</deletehash><name/>
  <link>https://i.imgur.com/xxxxx.png</link>
</data>

解決方法

レスポンスで返ってくるアップロードした画像の直URLの拡張子(上記例だと .png )を削除すると、画像のページのリンク(※)になるため、そのリンクであればcard表示されるようになるので、拡張子を排除した形でurlパラメータに渡してあげるようにした。

※こんなページ

ScreenCapture.CaptureScreenshotでAndroidビルドでエラーになった

事象

ScreenCapture.CaptureScreenshot は保存パスを設定すればそのパスに保存できるらしいという前提で実装していた。
Editor/WebGLビルドでは確かに問題なかった。
Androidビルドで実行した途端こんな感じのエラーに。。

11-15 21:10:56.490 12383 12401 I Unity   : capture_path = /storage/emulated/0/Android/data/com.Yasuragitei.UnityTweet/files/201911152110564885.png
11-15 21:10:56.490 12383 12401 I Unity   :
11-15 21:10:56.490 12383 12401 I Unity   : (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
11-15 21:10:56.490 12383 12401 I Unity   :
11-15 21:10:56.801 12383 12547 E Unity   : Failed to store screen shot (/storage/emulated/0/Android/data/com.Yasuragitei.UnityTweet/files/storage/emulated/0/Android/data/com.Yasuragitei.UnityTweet/files/201911152110564885.png)

capture_path = xxx は自前でloggingしたので、パス自体は問題なさそう……ただ
Failed to store screen shot の後ろに出力されてるパスが何かおかしい……

解決方法

こんな感じでモバイル向けはファイル名だけ指定して実行するようにした。

string fileName = string.Format("{0:yyyyMMddHmmssFFFF}.{1}", DateTime.Now, cImageSuffix);
string filePath = Application.persistentDataPath + "/" + fileName;

// モバイルプラットフォームはファイル名指定で、勝手にpersistentDataPath配下となる
#if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS)
ScreenCapture.CaptureScreenshot(fileName);
#else
ScreenCapture.CaptureScreenshot(filePath);
#endif

ちゃんとドキュメントを読みましょう

公式ドキュメントにはちゃんと書いてありました。
ScreenCapture.CaptureScreenshot
なので安心して Application.persistentDataPath 配下に保存される前提で処理が書けそう。

On mobile platforms the filename is appended to the persistent data path.
See Application.persistentDataPath for more information.

card表示の仕方がWeb版とTwitterクライアント版とで異なってた

事象

作りとしてキャプチャ画像のアップロード先のURLと、ゲームのURLの二つを共存する形でつぶやきたかった。
しかし、Web版はurlパラメータで指定したURLをcard表示してくれそうで、Twitterクライアント側ではURLの順序が早い方がcard表示対象になってしまうよう。

つまり、
こうしたかったけど

こうなってしまった

解決方法

こちらで解決できるような問題じゃなさそうだったので、パラメータを指定してあげることでImgurAPIを text/url 指定(Web版向け)で実行、もしくは textのみ 指定(URLの順序を画像URL優先にする)で実行できるようにちょっと無理矢理処理にした。

感想

  • 何でプラットフォーム間で動作が異なるんだ……
  • 困ったら公式ドキュメント。
  • ただ日本語ドキュメントは一部よくわからん翻訳になってたのでちょっと危険。