【Unity】InputSystemの「On-Screen Button」利用で発生したAndroid環境起因バグの原因分析および対応方法

2022-09-01Unity Tips

自作ゲームのご紹介

まずは自作ゲームのご紹介。

2022/7/14にAndroid向けアクションミニゲーム「突撃! ヨーコ道場」をリリースしました。

突撃!ヨーコ道場 – Google Play のアプリ

対象の人形を攻撃してよいかどうかの取捨選択(反射)だけでなく、攻撃する順番の考慮(思考)も必要となる、反射と思考が融合したアクションミニゲームです。

オンラインランキングで世界中の人達とスコアを競い合うことも可能。

片手で気軽に遊べるので、少しでも興味を持てたらぜひ遊んでみてください!(もちろんバグは解消済)

バグ内容

初めてのAndroidアプリのリリースということもあり、何度も実機でβテストを繰り返していたにもかかわらず、残念ながらリリース初日から致命的なバグが発生してしまいました。

自分のスマホを含め一部の環境では発生しない、環境起因バグとなります。

内容は下記の通り。

  • UnityのInputSystemにおいて、On-Screen Buttonのスクリプトを活用した入力方式(ボタン押下時、インスペクターで設定された入力を発生させる)を採用した箇所のみ、タップをしても反応しない(ゲームが進行しない)
  • どうもAndroid9以前は大丈夫だが、Android10以降だと発生するっぽい

初日からゲーム進行不可バグが発生、なおかつ自分のスマホでは発生しない環境起因=原因の調査と対応方法の模索が非常に困難……と、なかなかに苦い経験となった初リリースとなってしまいました。

原因分析

幸い仕事用のスマホ(Android10)では問題の再現が可能であったことから、原因を突き止めることができました。

結論からいうと「スマホに存在しない入力で処理しようとしていた」ことが原因です。

順を追って説明します。

バージョン1.00(リリース時)の入力仕様

バージョン1.00では、バーチャルコントローラまたは人形をタップした時に、キーボードの矢印キーが入力されたこととして扱うようにしていました。

しかし、当然のことながらスマホにはPCのようなキーボードは標準では存在しません。アルファベットや記号ならともかく、矢印キー入力はスマホ的にはありえない入力なんですね。

自分は「入力はあくまで信号でしかないのだから、実機ではありえない入力信号を送ったとしても、処理は問題なくできるだろう」と考えていました。

つまり、下記のように処理されるだろうと想定していた訳です。

ですが、結果からいえばどんなにボタンを押しても入力が発生した扱いにはなりませんでした。

このことから、あくまで仮説ですが、実際には下記のように実機の入力システムを中継して処理されているのではないか、と推測されます。

Android9以前では問題なく動作していたので、Android10以降で入力の取り扱いに何か変化があったのかもしれないですね。

バージョン1.01の入力仕様

矢印キーがだめなのなら、もう少しスマホでも現実的な入力にすればいけるんじゃないかと考え、ゲームパッドによる入力扱いとするよう設定を変更しました。

これはAndroid10では少なくとも解消が確認できたのですが、結局Android12では動かないままですというご報告をいただく結果となりました。

もしかするとAndroidのバージョンというより、その機種に導入されているキー入力システムの種類によるのかもしれないですね。

結論

「On-Screen Button」スクリプトを活用して別の入力扱いとするのなら、その実機で絶対に存在する入力扱いとしなければならない(存在しない入力で管理しようとするのはNG)。

よくよく考えてみれば「普通のこと」ではあるのですが、なまじ自分の実機(Android9)では問題なく動いてしまったがために、検知できなかったのが悔しいところですね……。

最終的な対応方法(バージョン1.02の入力仕様)

そもそも「On-Screen Button」スクリプトと、該当入力があった時のイベント処理で管理する方式自体が採用不可ということがわかりました。

そのため、入力とイベント処理で管理することをやめ、入力があったら直接操作メソッドを呼び出すスクリプトを作成し適用することにしました。

現在のバージョン1.02は下記のような処理となっているため、タップしても反応しないという不具合は発生しなくなった認識です(今のところ報告はないので、恐らく大丈夫なはず!)。

最初からそうしていればいいじゃんという話ではあるんですが、「On-Screen Button」とイベントを使った方が実装が簡単だったので楽した結果、大惨事となってしまいました……。

「On-Screen Button」スクリプトを使って入力を管理しようとしている方がいれば、ぜひともこの観点をご留意下さいませ。

Posted by yuumekou