今回はゲーム開発における耐久テストを行うための支援ツールについてお話します。実りが多いことと思います。使い方いきなりですが使い方から示します。持っていってください。debugTapMark.pngは便宜のために用意しただけで、別途好きな画像を使っていただいてもかまいません。サイズもお好みで良いですが、16x16から32x32くらいで良いかと思います。DefaultDebugTapperをどこかのGameObjectにつけます。Enabledをチェックします。これで、実行開始と共に8つのポインタが暴れ回って画面中をタップ、ドラッグ、長押しするようになります。どこかにEventSystemが存在している必要があるので、ご注意ください。コンポーネントのenabledはfalseにしておくのが良いかと思います。その子孫は叩かないようにしてあります。プロジェクトごとの事情に合わせられます。どこを叩くかカスタマイズしたいDefaultDebugTapperは全力で画面をランダムに叩きます。場面によってカスタマイズしたい事もあるでしょう。技選択モードでは技カードを優先的に叩きたい戦闘中に撤退ボタンは滅多に押したくないキャッシュクリアボタンを押されるのは困るドラッグがメインの入力系なので、ランダムだとゲームが進まないといったことが考えられます。カスタマイズするのは良い考えです。いうことも可能になります。人間が触る場合と極力同じ経路を通してテストすることが重要です。tapIndex)を実装すれば望みのことができます。DefaultDebugTapperの実装は以下のようになっています。3つの情報を指定してFire()を呼びます。場所はスクリーン座標です。凝って、そのシナリオを外部からスクリプトで与えることもできるでしょう。いう実装になっています。ほどよく長押しやドラッグが発生する匙加減にしており対数正規分布を使っています。非常に便利な分布なので、いずれ別の機会にブログにするかと思います。デバグ用のオブジェクトをシーンに置くと製品版にも入ってしまいます。私は極力これを避けるために、デバグ用のオブジェクトはコードで動的生成するようにしています。その場合、だいたい以下のようなコードを書くことになります。ManualStart()を呼びます。デバグ機能から有効化するまでは無効にしておきたいからです。起動と同時に乱打させたいなら不要ですが、そういうことはないでしょう。そのまま帰ることです。死んでいれば慌てて直す、ということになります。ほとんどゼロコストで、10時間以上×人数分のテストが毎日行われることになります。時給○○円でテストをお願いする、と仮定して計算してみてはいかがでしょう。以下のようなエラーで数秒のうちに死ぬこともあります。通信タイミングとUI入力の絡み合いで不正な状態になるエラーも起きやすいでしょう。自動タップをつっこむと大抵はひどいことになります。自動テストであれば率が低いバグでも低コストで再現させられる可能性があります。運用に際しては、できるだけ大量にAssertを入れて、ログに溜めておくと良いかと思います。それが一晩でだいたい150回くらい回っていました。一つでもあれば異常として修正する、ということを繰り返しました。一度もエラーが出ないことを確認する、というところまでやりました。予算と相談ということになるかと思います。可能であれば開発に普段使っているPCそのもので回して帰るのが理想です。やってそれに近づけるかは、ご所属の組織によっても違ってくるでしょう。「ほとんどタダで濃厚なテスト(QA)ができる」というコスト削減効果を捨てることになります。途端に面倒くさくなりました。手間の問題は軽視しない方が良いと思います。スマホ用のアプリであれば、ノートPCでも4つくらいは同時に起動できるはずです。すれば、テストの強度が4倍になります。standaloneビルドが動作する状況を作っておくと良いでしょう。standalone用のAssetBundleをビルドできるようにする、というのが一番面倒なところでしょうか。ログ機能は充実させておくことをおすすめします。ログは自動でslack等に集積すると良いでしょう。ログ機能デバグ支援のために、ログ機能を用意してあります。いうことがログに溜まっており、LogItemsやLogTextで取れます。場合、イベントが発火した先でやる処理は重くなりがちです。ような書き方はスパイクの原因になります。余計にメモリも食います。ある程度は動的に初期化する作りの方が妥当です。プロファイラで出るようにしておきました。OnPointerClickやOnPointerDownの下に重い処理があるかないかくらいはわかります。残念ながら実装は結構面倒くさいので、多少は説明しておこうと思います。基本はEventSystemに乗ることです。(もちろんEventSystemで入力を取っているアプリでの話ですが)。ExecuteEvents.ExecuteHierarchy()でイベントを発火させる。関しては何も文書がありません。見るしかない状態です。今回の実装は完全再現はしていません。再現度どれくらい再現しなければならないかは、アプリがどれくらい標準の挙動に依存しているかによります。公式と同じようにデータを入れねばなりません。Clickよりも先にUpが発火することに依存しているのであれば、合わせないといけません。しないとテストの価値が落ちてしまいます。今回の実装で標準に合わせないで手抜きをしたのは、主に以下です。必要なら標準に準拠させる作業をやっていただけると良いかと思います(是非私にください)。worldNormalはobsoleteなこともあって入れてないpointerPressとpointerDragの中身が微妙に違う公式だとdownのハンドラがなければupも来なくなるが、本実装はupだけでも発火する。中には意図して合わせていないものもあります。「公式の挙動が少し変わっただけで死ぬ潜在的な危険」も検出したいからです。公式の挙動は文書化されておらず、あくまで「今の実装」にすぎません。何ら仕様がないのです。みたいなことが多数あります。タッチによるドラッグ中には発火しません。押した時にEnter、離した時にExitです。タッチでは事実上使い物にならないし、実装も面倒くさいので、そもそも発火させないことにしました。「カードから指が外れた時にExitが来る」ことを期待するコードは危険です。エディタでマウスで操作していると発火するので、そういうものだと思ってしまいます(過去の私)。同様に「downのハンドラがないとupが来ない」も今回初めて知りました。途中で破棄!実装で一つ注意がいるのは、途中でオブジェクトが消える可能性を考えて書くことです。Downが発火したオブジェクトが、Upまで生きている保証はありません。途中でnullに化けた時のケアが必要です。厄介なことに、イベントは親に伝播します。上のImageに伝播します。使うかが変わってきます。このあたりも意識が必要です。公式ではUpはDownが発火したオブジェクトにしか発火しません。これに合わせるならExecute()の方を使うことになります(nullチェックしてないけどExecuteの第一引数ってnullでも大丈夫なんですかね?)。おわりに一番お伝えしたいことは「面倒くさいことは機械にやらせよう」ということです。この密度でタップを執拗に繰り返すテストは人間にはできません。数人で数時間触るのとは比較にならないほどの合計時間になります。それに近い状態を前もって再現するためにも、機械化が必要なのです。落ちるまでの平均時間をグラフ化してKPIに盛り込む座標の統計データを取って、「このあたりが危険」というヒートマップを作るといったツールの発展もありそうだ、とのこと。行けると良いのでは?という話でした。いうわけで夢は広がるのですが、実装は結構面倒ですので多少の気合が必要です。EventSystemの公式実装を読む羽目になってしまいました。私は「コードを読んだら負け」だと思うのですが、他にやりようがないのです。いう前提に立つ必要があります。最終的には完全再現が求められるのでしょう。実のところ、InputModuleは自作した方がいいんじゃないかと思ったりします。すれば正確な仕様を文書化してからアプリを作れます。アプリに渡さずに済みます。やめておいた方がいいですね。だましだまし使うことにしましょう。自作が標準と混ぜて使われたりしたら、どんな事故が起こるかわかったものではありませんから。画面写真をクリックするとサンプルのWebGLビルドに飛びます。...2019-07-17ベクトルを3D空間で回す画面写真をクリックするとWebGLビルドに飛びます。ソースコー...2019-06-17AudioClipなしで音が鳴る動的波形生成こんにちは。(1)月別アーカイブ検索スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。