
マイケル
さあアプリにSNS共有ボタンを追加するぞ〜〜!

エレキベア
急クマね〜〜〜
前つくったアプリにもついてた気がするクマ
前つくったアプリにもついてた気がするクマ

マイケル
そう、実は前作ったゴーゴーゴロヤン にも
下の画像のように共有ボタンはつけていたんだ。
下の画像のように共有ボタンはつけていたんだ。
↑ゴーゴーゴロヤンのSNS共有

マイケル
だけどこれは共有する機能が多すぎるし
ぶっちゃけ共有はTwitterだけでいいと思うんだよね
ぶっちゃけ共有はTwitterだけでいいと思うんだよね

エレキベア
確かにこれだけ種類があると選ぶ手間がかかるクマね

マイケル
そうなんだ、テストも大変だしね・・・

マイケル
というわけで今回はTwitterだけの共有機能を実装してみるよ!
↑Twitterのみの共有機能を追加する

エレキベア
やったるクマ〜〜〜〜
ツイッター共有の実装

マイケル
UnityでSNS共有の有名なライブラリといえば
SocialConnectorだね。
SocialConnectorだね。
最新版SocialConnector:
Social Connector v0.5.0

エレキベア
これはなかなか便利クマね

マイケル
そう、だけど最新版をそのまま使うと
ゴーゴーゴロヤンのように複数の共有画面を開く処理になってしまうんだ。
ゴーゴーゴロヤンのように複数の共有画面を開く処理になってしまうんだ。

マイケル
そのため、下記サイトを参考にさせていただいて過去バージョンをインポートする方法で実装してみようと思います!
参考サイト:
UnityでTwitterだけのシェアボタンを作る方法(画像付き)

エレキベア
過去バージョンでは共有機能が選べるようになっているクマね

マイケル
そのとおり!
さっそく実装してみよう!
さっそく実装してみよう!
過去バージョンをインポート

マイケル
記事で紹介されている通り、
下記のバージョンをインポートします!
下記のバージョンをインポートします!
過去バージョンSocialConnector:
Social Connector v0.2.9

マイケル
そしてインポートした後に何箇所か修正する点がありますが、
基本的に記事の通り実装すれば大丈夫です!
基本的に記事の通り実装すれば大丈夫です!
・SocialConnector.mmの編集
・Platform settingsの設定

エレキベア
この記事はわかりやすく説明してくれてるクマね
共有スクリプトの作成

マイケル
そして共有処理のスクリプトに関しては、
最終的には下記のようになりました。
最終的には下記のようになりました。
public class GameSceneManager : MonoBehaviour
{
・・・略・・・
// 共有ボタン押下時
public void PushShareButton()
{
// 共有画面を表示
StartCoroutine(_Share());
}
・・・略・・・
// SNS共有処理
public IEnumerator _Share()
{
string imgPath = Application.persistentDataPath + "/image.png";
// 前回のデータを削除
File.Delete(imgPath);
// 削除が完了するまで待機
while (true)
{
if (!File.Exists(imgPath)) break;
yield return null;
}
// スクリーンショットを取得
ScreenCapture.CaptureScreenshot("image.png");
// 撮影画像の書き込みが完了するまで待機
while (true)
{
if (File.Exists(imgPath)) break;
yield return null;
}
// 撮影画像の保存処理のため、1フレーム待機
yield return new WaitForEndOfFrame();
// 投稿する
string tweetText = "【ツイート内容】";
string tweetURL = "【ツイートURL】";
SocialConnector.PostMessage(SocialConnector.ServiceType.Twitter, tweetText, tweetURL, imgPath);
}
・・・略・・・
}

マイケル
前のスクショの削除 -> 新しいスクショの保存
の処理がそれぞれ終わるまで待機するようにしています。
の処理がそれぞれ終わるまで待機するようにしています。

エレキベア
保存や削除を行うのに若干のラグが発生してしまうクマね

マイケル
これで基本的に完了ですが、
一点、Android端末で画像が切り替わらない時がある
という不具合が発生しました。
一点、Android端末で画像が切り替わらない時がある
という不具合が発生しました。

マイケル
最新版では同じスクリプトで処理できたため、
何か足りていない処理があるのかどうか・・・。
原因を調査してみました!
何か足りていない処理があるのかどうか・・・。
原因を調査してみました!
不具合の原因

マイケル
不具合の原因を最新版のSocialConnectorの実装と見比べながら調べたところ・・・

マイケル
どうやら原因は、AndroidではAPI24からFileProviderを使用して画像の保存を行うようになっており、その対応が入っていないことのようでした。

エレキベア
権限の仕様が変わったのクマね
・SocialConnector.csの修正
・AndroidManifest.xmlの修正

マイケル
最新版では上記の修正がされていたため、
同じ修正を入れてあげます!
同じ修正を入れてあげます!
SocialConnector.csの修正

マイケル
まずはスクリプトの修正から!
インポートしたSocialConnector.csの105行目付近の下記処理をコメントアウトし
修正しましょう!
インポートしたSocialConnector.csの105行目付近の下記処理をコメントアウトし
修正しましょう!
----------------------------------------------------------------------------------------------
// *** UPDATE START ***
//if (!string.IsNullOrEmpty(textureUrl))
//{
// var uri = new AndroidJavaClass("android.net.Uri");
// var file = new AndroidJavaObject("java.io.File", textureUrl);
// intent.Call<AndroidJavaObject>("putExtra", "android.intent.extra.STREAM", uri.CallStatic<AndroidJavaObject>("fromFile", file));
//}
if (!string.IsNullOrEmpty(textureUrl))
{
var versionClazz = new AndroidJavaClass("android.os.Build$VERSION");
var apiLevel = versionClazz.GetStatic<int>("SDK_INT");
AndroidJavaObject uri;
if (24 <= apiLevel)
{
var context = activity.Call<AndroidJavaObject>("getApplicationContext");
var fileProvider = new AndroidJavaClass("android.support.v4.content.FileProvider");
var file = new AndroidJavaObject("java.io.File", textureUrl);
uri = fileProvider.CallStatic<AndroidJavaObject>("getUriForFile", context, Application.identifier + ".fileprovider", file);
}
else
{
var uriClazz = new AndroidJavaClass("android.net.Uri");
var file = new AndroidJavaObject("java.io.File", textureUrl);
uri = uriClazz.CallStatic<AndroidJavaObject>("fromFile", file);
}
intent.Call<AndroidJavaObject>("putExtra", "android.intent.extra.STREAM", uri);
}
// *** UPDATE END ***
----------------------------------------------------------------------------------------------
AndroidManifest.xmlの作成

マイケル
そしてFileProviderを使用できるよう、
AndroidManifest.xml を Assets/Plugins/Android 配下、
filepaths.xml を Assets/Plugins/Android/res/xml 配下
にそれぞれ作成しましょう!
AndroidManifest.xml を Assets/Plugins/Android 配下、
filepaths.xml を Assets/Plugins/Android/res/xml 配下
にそれぞれ作成しましょう!
・AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:theme="@style/UnityThemeSelector"
android:icon="@drawable/app_icon"
android:label="@string/app_name">
<activity
android:label="@string/app_name"
android:name="com.unity3d.player.UnityPlayerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="【自身のパッケージ名】.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"></meta-data>
</provider>
</application>
</manifest>
※2021/2/22 補足
一部環境では「android.support.v4.content.FileProvider」は使えず、
「androidx.core.content.FileProvider」を使うとうまく動作するようです。
(rygrep 様からの情報提供、詳細はコメント欄参照。)
・filePaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="unity_persistent_data_path" path="." />
</paths>

マイケル
AndroidManifestの【自身のパッケージ名】については、
自身のアプリのパッケージ名に置き換えましょう!
自身のアプリのパッケージ名に置き換えましょう!

エレキベア
ここまででちゃんとツイートできたクマ〜〜〜

マイケル
以上でTwitter共有処理の実装は完了です!
おわりに

マイケル
というわけで今回はTwitter共有の実装でした!
どうだったかな?
どうだったかな?

エレキベア
なんだかんだシンプルでいいクマね〜〜〜

マイケル
Tiwitter機能以外にも Facebook / LINE のみ
の実装も可能なので、是非やってみましょう!
の実装も可能なので、是非やってみましょう!

マイケル
それでは今日はこの辺で!
アデュー!!
アデュー!!

エレキベア
クマ〜〜〜〜〜〜〜