へくれすブログ

UnityとC#中心の備忘録です

【PlayFab】CloudScriptをGitHubで管理する方法

概要

f:id:hecres:20190728133856p:plain

PlayFab の CloudScript を Git(GitHub)で管理したい。
連携自体は簡単だが、いくつか分かりにくい部分があったためメモ。BC

解決方法

  1. PlayFab と GitHub の連携
  2. 【罠】Root ディレクトリ以外は反応しない
  3. 【罠】Push 内容をブラウザで確認可能になるまで時間がかかる
  4. 【仕様】Push しただけでは Deploy されない

PlayFab と GitHub の連携

PlayFab は公式で GitHub 連携をサポートしている。
公式ドキュメント以上のことは特にない。

【罠】Root ディレクトリ以外は反応しない

GitHub 連携では、リポジトリRoot 直下JavaScript ファイルを結合したものが CloudScript として扱われる。

例えば、ファイルを分類しようとして「root/Hoge/Fuga.js」のように配置すると無視される。

General Discussion - Multiple cloud script files
最後の「The feature does not seem to work anymore as of today...」の Reply に、
サブディレクトリに反応しない旨が書かれている。

【罠】Push 内容をブラウザで確認可能になるまで時間がかかる

master に push 後、処理自体は数秒程度で反映される一方、
ブラウザで目視確認できるようになるまでは多少時間がかかる。

当初は即時反映されるものと思い込んでいたため連携失敗と勘違いしてしまった。

【仕様】Push しただけでは Deploy されない

Push と Deploy は直接紐づいておらず、動作確認後に Deploy できるようになっている。
Deploy 前のリビジョンを使用するには、Request プロパティを以下のように指定する。

var request = new ExecuteCloudScriptRequest
{
  RevisionSelection = CloudScriptRevisionOption.Latest
};

General Discussion - GitHub and Cloud Scripts -- how does it work?

検証環境

Version
備考
PlayFabAllSDK 1.54.190717 UnitySDK でなく C#SDK を使用
Unity 2019.1.8f1

【Unity】PlayMakerFSMとZenjectの連携

概要

PlayMakerFSM を継承したステート処理に Zenject で値を Inject したい。

解決方法

  1. PlayMakerFSM の最初のステートで'zenjectReady'イベントを待機させる。
  2. すべての FsmStateAction を明示的に Inject する。
  3. zenjectReady イベントを流す。

PlayMakerFSM

後述の Inject 処理が終わるまで待機する。

f:id:hecres:20190706145427p:plain

明示的 Inject 処理

  1. シーン内にあるすべての PlayMakerFSM を取得
  2. 各 PlayMakerFSM 内にあるすべての FsmStateAction を取得
  3. DiContainer.Inject(FsmStateAction)で明示的に Inject

以下のコンポーネントを適当なオブジェクトにアタッチすると前述した一連の処理が実行される。

RunFSM で設定されたテンプレートにも対応。

検証環境

Version
Unity 2019.1.8f1

2017, 2018 でも動作したはず。

【Unity】【AssetStore】組織(企業/サークルなど)で購入したアセット管理のベストプラクティス

今回は技術ではなく権利まわりのお話です。
企業やサークルといった「組織」がAssetStoreでアセットを購入した場合の諸々についてです。

アセットをいくつ買えばいいの? とか
使っている人が退職した場合は? だとか
UnityProシートみたいに割り当てられないの? などなど

調べたり問い合わせたりしたので結果を書いていきます。

続きを読む

【Unity】InputFieldの編集終了が完了/キャンセルのどちらか判別する方法

InputFieldのOnEndEditイベント発行時にinputField.touchScreenKeyboard.statusを調べることで判別できます。
※TouchScreenKeyboard.isSupported=trueの環境のみ(Editor環境ではfalse)。

続きを読む

【Unity】コードから最新のYAMLクラスIDリファレンスを取得する方法

今回はYAMLクラスIDリファレンスを取得する方法についてです。
Unityの公式ドキュメントの情報が古いためリフレクションで強引に取得します。

f:id:hecres:20180317152302j:plain

YAMLクラスIDとは

YAML(ヤメル、ヤムル)はデータ形式の一種です。XMLやJSONなどの同類です。

そしてクラスIDとは、その名の通り各クラスに割り当てられたIDのことです。
GameObject=1、Component=2…といったように、Unity内の各クラスにはIDが割り振られています*1

どのクラスにどのIDが割り振られているかは、基本的にはUnity公式ドキュメントで公開されています。

currentドキュメント
YAML クラス ID リファレンス - Unity マニュアル

ちなみにversion 5.4以降のドキュメントはレイアウトが妙に見づらいので、
雰囲気を掴むには5.3のドキュメントのほうがお勧めです。

5.3ドキュメント
Unity - マニュアル: YAML クラス ID リファレンス

クラスIDが必要となる場面

PlayerSettings内のStrip Engine Codeをtrueにしている場合、クラスIDは非常に重要な情報です。

Strip Engine Codeとは、ビルド時にUnityエンジン側のコードを必要最低限のみ含める機能です。
使用されていないコードを除外することでビルドサイズの削減が見込め、特にWebGLでは影響が顕著に現れます。

しかし落とし穴もあり、この「必要最低限」にはAssetBundleが考慮されません。

あるコンポーネントが
「AssetBundle内で使用されている、かつ、アプリ本体側に含まれていない」場合
そのコンポーネントはビルドに含まれないため実行段階でエラーとなります。

エラーメッセージは「Could not produce class with ID 331」のような形式です。

この場合331=SpriteMaskがないぞと怒られているため、SpriteMaskをスプリット対象外に設定すれば解決できます。

指定クラスをスプリット対象外とするにはAssets直下にlink.xmlという名前のXMLファイルを作成します。

問題は冒頭で述べた通りUnity公式ドキュメントの情報が古く、
エラーメッセージで出たクラスIDが必ずしも載っているとは限らない点です。

SpriteMaskも本記事を書いている時点での最新版(2018.1ドキュメント)では記載されていません。

コードから最新のクラスIDを取得する方法

本題です。

クラスIDはUnityEditor.UnityTypesクラスが持っています。
UnityTypesクラスはinternal sealed定義となっているためリフレクションでアクセスします。

上記GetClassNameメソッドで指定したIDのクラス名が取得できます。

特定のIDを取得するのではなく、すべてをリストアップしたい場合は
上記メソッドをfor文で1200回ほど回してください。

Unity公式ドキュメントに記載されているIDは1120までなので
それだけ回せば全IDを取得できるはずです。

参考/関連

docs.unity3d.com
https://forum.unity.com/threads/yaml-class-id-reference.501959/

この記事でのバージョン

Version
Unity 2017.3.0p4
Unity/PlayerSettings/Scripting Runtime Version Experimental (.NET 4.6 Equivalent)

*1:なお、スクリプトで定義されたクラスはすべてMonoBehaviour=114のクラスIDが割り振られます。

【Unity】XcodeでのSimulatorビルドがクラッシュする問題について

以下のエラーメッセージに悩まされている方向けの記事です。
[UnityAppController renderingAPI] called before [UnityAppController selectRenderingApi]

f:id:hecres:20180316192302j:plain

現象

Target SDKをSimulator SDKに設定し、
Xcodeでシミュレーター向けのビルドを行うと

Uncaught exception: NSInternalInconsistencyException:
[UnityAppController renderingAPI] called before [UnityAppController selectRenderingApi]

とエラーが発生してクラッシュします。

実機ビルドやストア用のビルドでは正常に動作します。

原因と解決方法

Player Settings内のGraphics APIsにMetalのみ設定していることが原因のようです。
Graphics APIsにOpenGL ES 3などを追加するとシミュレーターモードでも動作します。

f:id:hecres:20180316190808j:plain

Metalのみ設定している場合にクラッシュするのは、調べた限りでは
XcodeのシミュレータがMetalをサポートしていないためのようです。

サポートしていない理由についてはAppleのデベロッパーフォーラムに
「シミュレータはエミュレータではなく、i386用に構築されたスタックを実行している」
という書き込みがありました。

つまりシミュレーターは32bitプロセッサ向けであり、
Metalは64bitプロセッサ用のグラフィックAPIなので対応できない?

iOS11で32bitアプリのサポートが終了したことですし、
シミュレーターも64bit向けに変わっていくのを期待したいところです。

参考/関連

answers.unity.com
forums.developer.apple.com

この記事でのバージョン

Version
Unity 2017.3.0p4
Unity/PlayerSettings/Scripting Runtime Version Experimental (.NET 4.6 Equivalent)

【Unity】【エディタ拡張】Project Settingsへのショートカット(ツールバー型)

2018/03/16追記

本記事を投稿した2日後に気が付いたのですが、 参考サイト様で既に完全上位互換のツールが公開されていました。

baba-s.hatenablog.com

baba-s.hatenablog.com

恥ずかしながら、記事作成時はまったく気が付いておりませんでした。

本記事のツールバーよりもコンパクトかつ汎用性に富んでいるため、
断然あちらのツールを使うべきです。

-----追記ここまで------------------------------

今回は各ProjectSettingsウィンドウ(とLightingウィンドウ)のショートカットを作ります。

f:id:hecres:20180310153142j:plain

ツールバー型です。

はじめは再生ボタンの左右に置こうかと思ったのですが、
あのスペースを活用するアセットもあるので普通のEditorWindowで作りました。

少し場所はとりますがそのほうが楽競合するリスクの回避を重視しました。

元ネタはこちら。
【Unity】Player Settingsを簡単に開けるようにするエディタ拡張 - コガネブログ
Project Settingsを簡単に開けるようにするエディタ拡張 - PanzerSoftのブログ

UnityのバージョンアップでEdit/Render Settingsが開けなくなっていたことと、
個人的に横長のツールバータイプが欲しかったので作りました。

成果物

どういった形で記事に載せるか迷ったのですが、とりあえず1ファイルにまとめてあります。

そのままプロジェクトに入れれば使えますが、
本来はnamespace=ディレクトリとして作成しています。

自分は結構細かくファイル・クラスを分割するタイプなので、ショートカット機能を実現するだけで6ファイルつくっています。
こういう書き方をするならGistではなくリポジトリを公開したほうがよいのかも……?

リポジトリを作ったらここに追記して載せておきます。

参考/関連

baba-s.hatenablog.com panzersoft.blog.fc2.com

この記事でのバージョン

Version
Unity 2017.3.0p4
Unity/PlayerSettings/Scripting Runtime Version Experimental (.NET 4.6 Equivalent)