KYUCON*BLOG tag:www.kyucon.com,2017-12-10:/blog/1 2020-06-11T12:44:11Z FlashとUnityの実験や、日常について、メモ代わりに載せていきます。 Movable Type Pro 6.3.6 [Unity] Android App Bundle(AAB)どこで設定するの? tag:www.kyucon.com,2020:/blog//1.466 2020-06-11T12:34:10Z 2020-06-11T12:44:11Z APKではなくAABにしたいのだけど、Unity 2018.4のBuild Se... okuyama <![CDATA[

APKではなくAABにしたいのだけど、Unity 2018.4のBuild Settingsを見ても
あるはずのBuild App Bundle (Google Play) の項目が見当たらない。

検索してもわからず時間を取られてしまったけど結論としては、
一つ上の項目であるBuild Systemを「Gradle」にすると出てきた!
Internalだと表示されない。

]]>
[Unity] Android App Bundle(AAB)どこで設定するの? tag:www.kyucon.com,2020:/blog//1.465 2020-06-11T12:34:10Z 2020-06-11T12:43:27Z APKではなくAABにしたいのだけど、Unity 2018.4のBuild Se... okuyama <![CDATA[

APKではなくAABにしたいのだけど、Unity 2018.4のBuild Settingsを見ても
あるはずのBuild App Bundle (Google Play) の項目が見当たらない。

検索してもわからず時間を取られてしまったけど結論としては、
一つ上の項目であるBuild Systemを「Gradle」にすると出てきた!
Internalだと表示されない。

]]>
Visual Effect Graphのカスタムアトリビュート tag:www.kyucon.com,2019:/blog//1.464 2019-08-12T07:26:03Z 2019-08-12T08:02:06Z Unity VFX Graphのサンプルを見ていると検索しても出てこないアトリビ... okuyama <![CDATA[

Unity VFX Graphのサンプルを見ていると
検索しても出てこないアトリビュートブロック("Base Position"とか"Offset 1" とか)を使っている事があり
いったいどうやって使うのか調べた結果、
下記のチェックボックスをONにすると使えるようになるという事だった。
Preferences -> Visual Effects > Experimental Operators/Blocks

ONにすると Set Custom AttributeブロックとGet Custom Attributeノードを作成できるようになる。
作成するとデフォルトはfloatだが、ブロックを選択してInspectorから型を変えたり、ランダムにしたり、Attribute名を変えたりできる。

]]>
Unity、iOSでアプリアップデート時にdeviceUniqueIdentifierが変わってしまう tag:www.kyucon.com,2019:/blog//1.463 2019-05-04T06:11:43Z 2019-05-25T01:12:31Z PlayFabのログインユーザーの識別IDとして、SystemInfo.devi... okuyama <![CDATA[

PlayFabのログインユーザーの識別IDとして、SystemInfo.deviceUniqueIdentifierを使用している状況で。
アプリのアンインストールなどせずに、ただAppStoreでアップデートしただけなのにIDが変化して新規ユーザー扱いになってしまう事象が2件発生した。
ユーザー端末は、いずれもiPhone8で iOS 11.3 と iOS 12.2 だった。
iOSのバグなのか不明だが非常に困る。

ひとまず対策として
初回のみ SystemInfo.deviceUniqueIdentifierを取得してPlayerPrefsに保存し、
2回目以降はPlayerPrefsに保存しておいた値を使うことにした。
アンインストールしない限りPlayerPrefsは残っているはずなのでたぶん大丈夫だと思う。

対策としてKeychainにIDを保存することにした。
Keychainに保存したデータは、たとえアンインストールしても残るのでPlayerPrefsより安心。
有償アセットiOS Keychain Pluginを使ったが、ネイティブ部分はunity-ios-keychain-pluginと同じだったので買わなくても良かったかも。
有償の方は、iOS以外の場合にpersistentDataPathに暗号化したファイルとして保存するようになっていた。

]]>
PlayFabのローカライズ tag:www.kyucon.com,2019:/blog//1.462 2019-03-23T07:45:05Z 2019-03-23T08:23:10Z 言語ごとに表示内容を変える方法について。ニュース、メール、プッシュ通知については... okuyama <![CDATA[

言語ごとに表示内容を変える方法について。
ニュース、メール、プッシュ通知については管理画面で各言語ごとに文章を登録できるようになっている。
これらはプレイヤーのLanguage設定に従って自動で表示文章が選ばれる。
プレイヤーのLanguageが未設定だったり、一致する言語がない場合はデフォルト言語で表示される。
デフォルト言語は管理画面のSettings>Default languageで設定する。

クライアントからプレイヤーの言語を登録する方法は下記のような感じで、Profile.VersionNumberが必要になるので先に取得してから、SetProfileLanguage APIを呼ぶ。


//言語を登録する
    public static void SetLanguage(string language)
    {
        //先にプロフィールのバージョン番号を取得する
        GetProfile((version) => {
            //取得したバージョン番号を用いて言語登録
            SetProfileLanguage(language, version,(success)=> {
                if(success){
                    Debug.Log("登録完了");
                }else{
                    Debug.Log("登録失敗");
                }
            });
        });
    }
//プロフィールのバージョン番号を取得する
    private static void GetProfile(System.Action callback) {
        PlayFabProfilesAPI.GetProfile(new GetEntityProfileRequest{}, result => {
            callback.Invoke(result.Profile.VersionNumber);
        },error => {});
    }
//言語登録APIを実行する
    private static void SetProfileLanguage(string language,int profileVersion, System.Action callback)
    {
        var request = new SetProfileLanguageRequest
        {
            Language = language,
            ExpectedVersion = profileVersion
        };
        PlayFabProfilesAPI.SetProfileLanguage(request, res =>
        {
            callback.Invoke(true);
        }, error=> {
            callback.Invoke(false);
        });
    }

Unityで取得できるOSの言語(Application.systemLanguage)をPlayFabの言語コードに変換するには下記のようになると思う。 (PlayFabのドキュメントに言語コード一覧が見当たらなかったので、管理画面のプルダウンで使用されている言語コードを使用)
※Application.systemLanguageで取得できる言語数より、PlayFabで設定できる言語数のほうが多いが割愛
※ノルウェー語やセルビアクロアチア語は、PlayFabでは2種類に分かれるが独断で選んだ。


    public static string GetLanguageCode()
    {
        switch (Application.systemLanguage)
        {
            case SystemLanguage.Afrikaans: return "af";//アフリカ語
            case SystemLanguage.Arabic: return "ar";//アラビア語
            case SystemLanguage.Basque: return "eu";//バスク語
            case SystemLanguage.Belarusian: return "be";//ベラルーシ語
            case SystemLanguage.Bulgarian: return "bg";//ブルガリア語
            case SystemLanguage.Catalan: return "ca";//カタロニア語
            case SystemLanguage.Chinese: return "zh-Hans";//中国語
            case SystemLanguage.ChineseSimplified: return "zh-Hans";//中国語簡体字(simplified)
            case SystemLanguage.ChineseTraditional: return "zh-Hant";//中国語繁体字(traditional)
            case SystemLanguage.Czech: return "cs";//チェコ語
            case SystemLanguage.Danish: return "da";//デンマーク語
            case SystemLanguage.Dutch: return "nl";//オランダ語
            case SystemLanguage.English: return "en";//英語
            case SystemLanguage.Estonian: return "et";//エストニア語
            case SystemLanguage.Faroese: return "fo";//フェロー語
            case SystemLanguage.Finnish: return "fi";//フィンランド語
            case SystemLanguage.French: return "fr";//フランス語
            case SystemLanguage.German: return "de";//ドイツ語
            case SystemLanguage.Greek: return "el";//ギリシャ語
            case SystemLanguage.Hebrew: return "he";//ヘブライ語
            case SystemLanguage.Hungarian: return "hu";//ハンガリー語
            case SystemLanguage.Icelandic: return "is";//アイスランド語
            case SystemLanguage.Indonesian: return "id";//インドネシア語
            case SystemLanguage.Italian: return "it";//イタリア語
            case SystemLanguage.Japanese: return "ja";//日本語
            case SystemLanguage.Korean: return "ko";//韓国語
            case SystemLanguage.Latvian: return "lv";//ラトビア語
            case SystemLanguage.Lithuanian: return "lt";//リトアニア語
            case SystemLanguage.Norwegian: return "nb";//ノルウェー語(ブークモール)
            case SystemLanguage.Polish: return "pl";//ポーランド語
            case SystemLanguage.Portuguese: return "pt";//ポルトガル語
            case SystemLanguage.Romanian: return "ro";//ルーマニア語
            case SystemLanguage.Russian: return "ru";//ロシア語
            case SystemLanguage.SerboCroatian: return "sr-Latn";//セルビアクロアチア語 (Serbian (Latin))
            case SystemLanguage.Slovak: return "sk";//スロバキア語
            case SystemLanguage.Slovenian: return "sl";//スロベニア語
            case SystemLanguage.Spanish: return "es";//スペイン語
            case SystemLanguage.Swedish: return "sv";//スウェーデン語
            case SystemLanguage.Thai: return "th";//タイ語
            case SystemLanguage.Turkish: return "tr";//トルコ語
            case SystemLanguage.Ukrainian: return "uk";//ウクライナ語
            case SystemLanguage.Vietnamese: return "vi";//ベトナム語
            default: return "en";
        }
    }

インベントリアイテム名などはローカライズシステムが整っていないので、CustomDataにjson形式で文言を入れておいて自前で選ぶ。

]]>
[Unity ] 透過動画(WebM VP8)を作ったときのメモ tag:www.kyucon.com,2019:/blog//1.461 2019-03-21T14:09:59Z 2020-02-22T02:16:09Z Unityでサポートしているアルファチャンネル付き動画の形式はWebM(動画コー... okuyama <![CDATA[

Unityでサポートしているアルファチャンネル付き動画の形式はWebM(動画コーデックはVP8、音声コーデックはVorbis)。

FFmpegを使って、PNG連番画像をWebMにするなら下記で良い。

ffmpeg -r 30 -i frames\%04d.png -auto-alt-ref 0 -c:v libvpx -b:v 5M output.webm

今回、音声コーデックがOpus形式のWebMファイルがあり、そのままではUnityで読み込めないためVorbis形式に変換する必要があった。
一発でいけるかもしれないけど、うまくできなかったので下記のような手順を踏んだ。
1)サウンドだけ抜き出す

ffmpeg -i original.webm -acodec libmp3lame -aq 4 sound.mp3

2)映像をいったん連番PNGに書き出す

ffmpeg -vcodec libvpx -i original.webm frames\%04d.png

3)連番PNGをWebMファイルに変換(その際フレームレートを60から30に変換、解像度を640x360に変更、ビットレートは20000kb/s)

ffmpeg -framerate 60 -i frames3\%04d.png -vf fps=30 -s 640x360 -auto-alt-ref 0 -c:v libvpx -pix_fmt yuva420p -metadata:s:v:0 alpha_mode="1" -b:v 20000k -r 30 noSound.webm

4)無音のWebMにサウンド(Vorbisコーデック)をつける

ffmpeg -i noSound.webm -i sound.mp3 -c:v copy -c:a libvorbis -map 0:v:0 -map 1:a:0 final.webm


なお、Androidで再生する場合は
Unityの映像ファイルのImport SettingsでTranscodeをオンにしてCodecをVP8にする必要がある。

映像をPlaneとかに貼り付けて透過表示するにはマテリアルのシェーダーをUnlit/Transparentにすれば良い。

]]>
PlayFabの不具合とか tag:www.kyucon.com,2019:/blog//1.460 2019-03-16T10:14:20Z 2019-03-23T07:42:18Z ゲームのバックエンドプラットフォーム「PlayFab」について。一通り機能が揃っ... okuyama <![CDATA[

ゲームのバックエンドプラットフォーム「PlayFab」について。
一通り機能が揃っていて自前で用意する手間が省けるし、
インディープランもあるのでみんな使えばいいと思う一方でたまに変な不具合が起きて心配になる。
基本的にサービスは安定していると思うけど、これまでに主に管理画面側で遭遇した不具合を記しておく。

・Title News APIで、ある日を境にエラーが起きるようになった。
→Newsのローカライズ機能が告知なく実装され、既存のニュース記事があるとデータ取得できない状態に。機能リリース前にテストしてないのかな。

・他人のタイトルのニュースが混入して消せない現象。
→サポートチケット書いたら、インディープランは個別サポートしないのでフォーラムに投稿せよとのこと。1,2週間で直った。

・管理画面のメニューが押せない現象。
→日本語でのみ発生、1日くらいで直った。

・特定のLeaderboadのみ「StatisticAlreadyHasPrizeTable」エラーが出てPrize Tablesを作成できない。
→フォーラムに報告したらすぐに対応してもらえた。

ついでに欲しい機能:
・間違って作ったLeaderboardを消したいな。
・ユーザー毎のデータは充実してるけど、タイトル全体の統計情報(総プレイ回数とか流通コイン総額とか)を保存するデータベースがあればなぁ。
・有償コインと無償コインをまとめて扱う機能。現状はCloudScriptで実装。

]]>
アドフリくん Unity動画広告SDKのパーミッション tag:www.kyucon.com,2019:/blog//1.459 2019-03-05T05:54:48Z 2019-03-05T06:00:41Z アドフリくんのUnity動画広告SDK Ver.2.20.1から下記のAndro... okuyama <![CDATA[

アドフリくんのUnity動画広告SDK Ver.2.20.1から
下記のAndroidパーミッション要求が自動で追加されるようになった。

・SDカードのコンテンツの読み取り(SmaAdで使用
・SDカードのコンテンツを修正/削除する(SmaAdで使用)
・Wi-Fiからの接続と切断(Tapjoyで使用)

これらのパーミッションを取り除くためには、
/Assets/Plugins/Android/AndroidManifest.xmlに下記を追記する必要があるとの事。

・SDカードのコンテンツの読み取り
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove"/>
・SDカードのコンテンツを修正/削除する
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove"/>
・Wi-Fiからの接続と切断
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" tools:node="remove"/>
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" tools:node="remove"/>

]]>
PlayFabのセッション切れ tag:www.kyucon.com,2018:/blog//1.458 2018-12-23T08:34:56Z 2018-12-23T08:41:18Z PlayFab APIはログインから24時間経つとセッションが切れて、下記のエラ... okuyama <![CDATA[

PlayFab APIはログインから24時間経つとセッションが切れて、下記のエラーが起きる。

{
"code": 401,
"status": "Unauthorized",
"error": "NotAuthenticated",
"errorCode": 1074,
"errorMessage": "X-Authentication HTTP header contains invalid ticket"
}

ゲームを中断して、次の日に続きを遊ぶ場合などに起こり得るので、エラーチェックと再ログインを実装しておかないといけない。

]]>
Unity + PlayFabで課金処理 tag:www.kyucon.com,2018:/blog//1.457 2018-12-15T14:51:11Z 2018-12-15T15:58:41Z App Store,Google Play Storeの課金処理はUnity I... okuyama <![CDATA[

App Store,Google Play Storeの課金処理はUnity IAPで行って、レシートチェックとアイテム付与をPlayFabAPIで行う。
以下、要所だけ載せます。


//////////////////////////
// Unityの課金システム構築
StandardPurchasingModule module = StandardPurchasingModule.Instance();
ConfigurationBuilder builder = ConfigurationBuilder.Instance(module);
//商品ID登録(ストアに登録したIDとPlayFabのカタログアイテムIDを統一しておくと面倒がない)
builder.AddProduct("MyItemID", ProductType.Consumable);
// 非同期の初期化を開始
UnityPurchasing.Initialize(this, builder);


//////////////////////////
//Unity IAP 初期化完了時
//////////////////////////
void OnInitialized(IStoreController controller, IExtensionProvider extensions){
	//ストアの表示価格は下記のようにして取得
	Product p=controller.products.WithID("MyItemID");
	Debug.Log(p.metadata.localizedPriceString);
}


//////////////////////////
//購入ボタン押した時
//////////////////////////
controller.InitiatePurchase("MyItemID");


//////////////////////////
//購入完了時の呼ばれる関数
//////////////////////////
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e){
	//プロダクト不明のため無視
	if (e.purchasedProduct == null){
		return PurchaseProcessingResult.Complete;
	}
	//レシートがないので無視
	if (string.IsNullOrEmpty(e.purchasedProduct.receipt)){
		return PurchaseProcessingResult.Complete;
	}
	//レシート検証&アイテム付与。iOSとAndroidで分岐
	if (Application.platform == RuntimePlatform.Android){
		ValidateAndroidPurchase(e.purchasedProduct);
	} else {
		ValidateIosPurchase(e.purchasedProduct);
	}
	//PlayFabでレシート検証完了するまでペンディングにする
	return PurchaseProcessingResult.Pending;
}

//////////////////////////
//Androidのレシート検証&アイテム付与
//////////////////////////
private void ValidateAndroidPurchase(Product purchasedProduct) {
	var googleReceipt = GooglePurchase.FromJson(purchasedProduct.receipt);
	PlayFabClientAPI.ValidateGooglePlayPurchase(new ValidateGooglePlayPurchaseRequest()
	{
		CurrencyCode = purchasedProduct.metadata.isoCurrencyCode,
		PurchasePrice = (uint)(purchasedProduct.metadata.localizedPrice * 100),
		ReceiptJson = googleReceipt.PayloadData.json,
		Signature = googleReceipt.PayloadData.signature
	}, result =>
	{
		//購入処理が完了したものとする
		controller.ConfirmPendingPurchase(purchasedProduct);
		//TODO:インベントリ更新するなど
	},
	error =>
	{
		//使用済みレシートが残っていた場合は完了扱いにする
		if (error.ErrorMessage == "Receipt already used"){
			controller.ConfirmPendingPurchase(purchasedProduct);
		}
	}
	);
}

//////////////////////////
//iOSのレシート検証&アイテム付与
private void ValidateIosPurchase(Product purchasedProduct){
	Dictionary receipt=PlayFabSimpleJson.DeserializeObject>(purchasedProduct.receipt);
	var request = new ValidateIOSReceiptRequest
	{
		CurrencyCode = purchasedProduct.metadata.isoCurrencyCode,
		PurchasePrice = (int)(purchasedProduct.metadata.localizedPrice * 100),
		ReceiptData = (string)(receipt["Payload"])
	};
	PlayFabClientAPI.ValidateIOSReceipt(request, result =>
	{
		//購入処理が完了したものとする
		controller.ConfirmPendingPurchase(purchasedProduct);
		//TODO:インベントリ更新するなど
	},
	error =>
	{
		//使用済みレシートが残っていた場合は完了扱いにする
		if (error.ErrorMessage == "Receipt already used"){
			controller.ConfirmPendingPurchase(purchasedProduct);
		}
	}
	);
}
]]>
iOS IAP Sandboxアカウントの切り替え tag:www.kyucon.com,2018:/blog//1.456 2018-12-13T17:46:07Z 2018-12-13T17:52:10Z 「設定> iTunesとApp Store」でログアウトしてるのにSandbox... okuyama <![CDATA[

「設定> iTunesとApp Store」でログアウトしてるのにSandbox用のアカウントを選べない状況。
購入ボタンを押すと"Confirm Your In-App Purchase"ダイアログが表示されるが アカウント入力欄が無く、パスワードしか尋ねられない。
どうやるのか探し回った結果、
「iTunesとApp Store」をスクロールした下の方にSANDBOXアカウントの項目があった
昔からありました?

]]>
PlayFabの使い方 ログを採る tag:www.kyucon.com,2018:/blog//1.455 2018-12-08T17:50:35Z 2018-12-15T16:07:55Z ユーザーの操作ログやエラーログをサーバーに送るには下記のような感じで実行するとP... okuyama <![CDATA[

ユーザーの操作ログやエラーログをサーバーに送るには下記のような感じで実行するとPlayStreamに記録される。


PlayFabClientAPI.WritePlayerEvent(new WriteClientPlayerEventRequest()
	{
		Body = new Dictionary() {{ "foo", "bar"}},
		EventName = "my_custom_event"
	},
	result => Debug.Log("Logged"),
	error => Debug.LogError(error.GenerateErrorReport())
);


ログイン完了していないとAPI実行できないのでログインエラーのタイミングでは送れない。]]>
PlayFabの使い方 ユーザーデータ周り tag:www.kyucon.com,2018:/blog//1.454 2018-12-08T16:13:59Z 2018-12-15T16:10:51Z ゲームアプリのバックエンドとしてPlayFabを触り始めました。一通り機能が揃っ... okuyama <![CDATA[

ゲームアプリのバックエンドとしてPlayFabを触り始めました。一通り機能が揃っていてすごく便利な感じです。
英語ドキュメントやフォーラムを検索すれば大抵の事は解決しますが、日本語情報が少ないのでここにメモしておきます。

まずユーザーに紐づく情報をどう取得または保存するかについて、下記のように使い分けるのが良さそうです。

・プレイヤー表示名...
  PlayerProfileのDisplayNameで取得。UpdateUserTitleDisplayNameで更新。

・プレイヤーの経験値やハイスコアなどの数値...
  Statisticsデータとしてサーバー側のCloudScriptを呼び出して保存する。
  不正対策としてクライアントからは直接書き込めないようにデフォルト設定されている。
  Statisticsとして保存しているデータはLeaderboard(ランキング機能)として扱える。

・ゲーム内通貨の所持数...
  GetPlayerCombinedInfoのUserVirtualCurrencyで取得。
  不正対策としてクライアントからは通貨の加算減算ができないようにデフォルト設定されている。

・武器やアイテムやスキルの所持フラグ...
  マスター情報はCatalogで管理し、ユーザーの所持データはGetUserInventoryで取得。
  販売アイテムじゃない物はprice 0でカタログ登録しておき、サーバー側のGrantItemsToUserで付与するか、クライアント側のPurchaseItemで所持する。

・フレンド情報...
  GetFriendsListAddFriendを使う。
  フレンドというより一方的なフォロー登録なので、相互フォローしたいなら自前で処理を書く。

・そのほか諸々のユーザ情報...
  UserDataとして取得や保存する。
  クライアントから書き換えられたくないデータは、サーバー側でUpdateUserReadOnlyDataを使う。


ログイン時にまとめてデータを取得するには、下記のようにGetPlayerCombinedInfoRequestParamsを指定する。


GetPlayerCombinedInfoRequestParams InfoRequestParams = new GetPlayerCombinedInfoRequestParams()
{
	GetPlayerProfile = true,
	ProfileConstraints = new PlayerProfileViewConstraints()
	{
		ShowDisplayName = true
	},
	GetPlayerStatistics =true,
	GetUserInventory = true,
	GetUserData = true,
	GetUserReadOnlyData = true,
	GetUserVirtualCurrency = true
};

PlayFabClientAPI.LoginWithCustomID(
	new LoginWithCustomIDRequest()
	{
		TitleId = PlayFabSettings.TitleId,
		CustomId = SystemInfo.deviceUniqueIdentifier,
		CreateAccount = true,
		InfoRequestParameters = InfoRequestParams
	}, 
	(result) => {}, 
	(error) => {}
);
]]>
Photon Unity NetworkingのPhotonTransformViewで微妙にずれる tag:www.kyucon.com,2018:/blog//1.452 2018-09-15T17:38:44Z 2018-09-16T09:03:11Z 位置同期をPhotonTransformViewで行う際、補間処理(Interp... okuyama <![CDATA[

位置同期をPhotonTransformViewで行う際、
補間処理(Interpolate Option)は「Estimated Speed」を使うのが良さそうなのだが
移動停止した時の座標が完全に同期せずわずかにずれたままになる現象がある。

これを解消するには、PhotonTransformViewPositionControl.csの91〜94行目あたりを下記のようすると良さそう。

float estimatedSpeed = (Vector3.Distance(m_NetworkPosition, GetOldestStoredNetworkPosition()) / m_OldNetworkPositions.Count) * PhotonNetwork.sendRateOnSerialize;
if (estimatedSpeed < 1f)
{
currentPosition = targetPosition;
}
else
{
// move towards the targetPosition (including estimates, if that's active) with the speed calculated from the last updates.
currentPosition = Vector3.MoveTowards(currentPosition, targetPosition, Time.deltaTime * estimatedSpeed);
}

要は、推定速度がほぼ0になってしまうと最後まで移動してくれないので
速度 1f未満なら強制的に目標値ぴったりに移動させている。

Photonを使い始めるにあたっては下記の記事がすごく丁寧で分かりやすい。
【Unity】僕もPhotonを使いたい #01〜#14

]]>
[Unity] AndroidのWebViewでHTML5 videoを表示 tag:www.kyucon.com,2018:/blog//1.451 2018-09-01T11:33:20Z 2018-09-01T12:09:41Z AndroidのWebViewでYoutubeなどvideoタグを使った映像再生... okuyama <![CDATA[

AndroidのWebViewでYoutubeなどvideoタグを使った映像再生をしようとしてはまった点をメモ。
WebViewプラグインはgree/unity-webviewを使用。

1)まず、映像が表示されない現象。(音だけ流れて、画面表示は黒か白のまま)
AndroidManifestのandroid:hardwareAccelerated="true"は正しく記述されているのに発生した。
これについてはUnityのバージョンを上げたら解消。
2017.4.10→NG
2018.1.1 →OK

2)映像再生前にとてもダサい再生ボタンが表示される問題。

これはvideoタグのposter属性がない場合にデフォルトで差し込まれるらしい。
Chromeブラウザでは表示されないのにWebViewで見ると表示される。
消すにはWebViewPlugin.javaを書き換えて.jarをビルドしなおす必要がある。

plugins/Android/src/net/gree/unitywebview/CWebViewPlugin.javaを開き、117行目あたりを下記のように変更。

webView.setWebChromeClient(new WebChromeClient() {
 View videoView;
 //透明の画像を返す処理を追記
 @Override
 public Bitmap getDefaultVideoPoster() {
  return Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
 }

あとはビルドして出来上がったplugins/Android/bin/WebViewPlugin.jarをUnityのAssets/Pluginsに持っていくだけ。
ビルド手順はgree/unity-webviewに書かれているが、JDK10だと下記のエラーが出てビルドが通らない。
Could not determine java version from '10.0.1'
Gradleのバージョンの問題らしいが、Gradleのバージョンを変えてうまくビルドできなかったので、
JDK8をインストールすることで回避。

]]>