原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【小ネタ】InputSystemからの入力とUI操作との競合を防ぎたい

バージョンアップ

Unityのバージョンアップには毎度冷や汗をかく臆病者の皆さんこんにちは。先日今後のことも考えてUnity2022からUnity6.0へバージョンアップしたのですが作りかけのプロジェクトで案の定エラーが複数個表示され冷や汗を書きました。Unity本体をバージョンアップする際には不要なアセットを削除して、アプデ後にはLibraryフォルダを一度消した方が良いと思います。あと当然ながらバックアップを忘れずに。

 

数をこなして覚えましょうなゲーム

世間ではきっとナイトレインで賑わっているでしょうが、ボッチ人間には手が出しづらいので評判の良かったソウルライクゲームを購入しました。

 

ソウルライク定番のダークファンタジーな世界が舞台の高難易度アクションRPGゲームで、キャラクターはアニメ調のトゥーンレンダリングが採用されておりCODE VEIN辺りに見た目は似てますが、プレイ感覚はソウルライクというより仁王ライクと言った方が良いと思います。
手に入る武器防具にランダム特性が付いていたり、武器防具の同種による揃え効果があったり、ステージはミッション形式で一度ステージを離脱して他のステージを探索後戻ったりすると、それまでのショートカットやギミックの解除がリセットされるなど、ゲームルールは完全に仁王・ウォーロンの影響を受けています。

その為か敵(ボス)の攻撃はかなり激しく早い攻撃ばかりで、それに打ち勝つには相手の攻撃を見極めてパリィやジャスト回避といった行動を組み合わせることが必要になります。まぁウォーロンほどパリィを強要されませんが、エルデンリングのように色んな武器・戦技・魔法の中から戦略を考えて敵に対峙する的な攻略要素は少なく、ひたすら相手のモーションとタイミングを覚えててカウンターを決めるなり回避するなりの行動を取ることが必要で、その苦行の繰り返しが楽しいと思えるかがこのゲームを楽しめるかの分水嶺になっています。

ソウルライクの中でも仁王・ウォーロンの系譜が好きな方はこのゲームに適応できて楽しむことができますが、エルデンリングのようなプレイ感覚を求める方は少し合わないゲームなのではないでしょうか。

 

InputSystemは使いやすい

Unity2022以降のバージョンを使う場合は旧Unity.Input APIを使うよりもInputSystemを使うケースの方が多いかと思います。
Input Systemではマウスやキーボード、ゲームパッドなどあらゆる入力デバイスを一元で管理できるInputActionが用意されており、それを使えばマウスの左クリックとスマホ画面のタッチ入力が同じイベントとして扱うことが出来るのでデバイスの違いを意識せずにスクリプトを組むことができます。

docs.unity3d.com

InputSystem使用下でのUI操作にはEventSystemにアタッチされたInputSystem UI InputModuleを使用しますが、こちらはシーン内にCanvasを作成する際に自動で付与されていたりするので特に意識することなくボタンクリック等のイベントも発火させることが出来ます。

このボタンクリックは当然ながらマウスの左クリックや画面のタッチ操作によって操作されます。そしてInputActionによるマウスの左クリックおよび画面のタッチも同時にイベントして発火されます。このため、普通に実装するとゲーム画面のUI操作(ボタンクリック)とゲームの操作入力が競合する状態になります

 

競合を避けたい

例としてマウスの左クリックを押下(ドラッグ)すると前に進み、離すと止まる、という操作のゲームを考えます。
この状態で画面内に一時停止用のボタンを配置してやると

ボタン押下による一時停止と同時に少し操作キャラクター(ペンギン)が前に進んでいる事がわかると思います。

このようなケースではInputActionによる発火イベント内でEventSystemのIsPointerOverGameObjectを参照する事がもっとも簡単な実装かと思います。

// Input Actionのperformedコールバック
public void OnCallBack_OnFire(InputAction.CallbackContext context)
{
    // UIの上にカーソルがあったら、入力を受け付けない
    if (EventSystem.current.IsPointerOverGameObject()) return;

    // ボタン押下時の処理
    Event_OnFire();
}

この手法は全てのUIを対象としてUI上にカーソルなどがあれば入力をブロックする方法です。そのため、ImageコンポーネントなどのUIも対象となるため注意が必要ですが、ボタンだけとしたい場合はRayキャストを飛ばしてUI要素を取得し型チェックするなど少し面倒な実装になるので、画面中に不要なUIを表示しない等の対策をして上記のコードを実装するのがおすすめです。

この対処を先ほどのゲームに実装した結果は以下のようになります。

一時停止ボタン押下してもキャラクターが前進しなくなりました。

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。