以下の内容はhttps://www.karvan1230.com/entry/2025/06/03/221031より取得しました。


【小ネタ】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を表示しない等の対策をして上記のコードを実装するのがおすすめです。

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

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




以上の内容はhttps://www.karvan1230.com/entry/2025/06/03/221031より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14