レスポンスの悪さに気づく(9)

このゲームも、「早くたたく」「素早く逃げる」といった曲がりなりにもアクションゲームです。
そんなわけで、フレームレートも自分なりに意識してみました。

…まあ、ぶっちゃけこのゲームでフレームレートがどうこうはないですね…。

PCでしか実行していないので絵もガバガバ大サイズ(2000x2000とか。後程縮小しようと思っていますが…)。それでも、表示物が単純かつ極限まで少ないですから、処理落ちなどまずありえません。

マウスでプレイするとクリアできない

処理落ちなどありえない。
それなのに、キーボードで自分なりにほぼクリアできるラインが、マウスではクリアできない。
なぜなのか。

マウスとタップの共通化は時と場合を選ぶ

マウス操作は、タップと共通化を図るため、次のようなオペレーションになっていました。

叩く場合はキャラにカーソルを合わせて左クリック
逃げる場合は画面端にカーソルを合わせて左クリック

なお、タップの場合「カーソルを合わせる」必要はありません。(カーソルがそもそもない)

これは、問題の正解・間違いを判断し、一定時間内に叩く・逃げるを選択するこのゲームの性質上、マウスだけ難易度が上がるオペレーションです。

指定箇所にカーソルを合わせる作業は、例えマウスを使い慣れていたとしても難しいですし、そもそもマウスだけ1オペレーション増えているので、いくらカーソルを合わせるのが速くても、他の入力にくらべて不利が消えることはありません。

スマフォのタッチ操作と、マウス操作は似ているようだが、ゲーム(性)によっては共通化できない。
そのことをきちんと考慮する必要がありました。

今回のゲームの場合、叩く・逃げるを「左クリック」「右クリック」とすることで、その問題を解決しました。これならキーボードやタップと同じ条件になります。

しかし、もっとゲームルールが複雑だった場合、この手は使えなかったかもしれません。
最悪の場合マウスに合わせてゲームのリバランスが必要になり、結果キーボードやタップでやるとヌルゲーといった形になっていたかもしれません。

スマフォでドラッグが必要なゲーム、私は湿気の多い指のせいかあれが苦手で、反面マウスでやるととても簡単になります。なんて事もあったりします。

まだ少しマウスの反応が悪い(気がする)

これはしばらく

気のせいだろう

と思い込むようにしていましたが、やればやるほどほんの少しマウスをクリックしてから叩く(逃げる)までにラグ(時間差)があると感じるようになりました。

ラグ=処理落ち? と脊髄反射的に思いましたが、そうであれば反応のいいキーボードの説明がつきません。
マウス自体の反応が悪いのか…Bluetooth だし…。とも考えてみましたが、時折物凄くラグがある(ように感じる)し、第一ウチのキーボードだって Bluetooth でした。
さすがに犯人扱いは出来そうにありません…。

色々とマウスでの操作をしていると、あることに気がつきます。

あれ?
これって、ボタン離した時に判定されてないか…?

原因は、マウスイベントにありました。

public class CollisionPlayer : MonoBehaviour, IPointerClickHandler
{
    void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
    {
    }
}

IPointerClickHandler

このイベントはマウスをクリックした時に発生するイベントですが、厳密にいうと

マウスのボタンを押した

マウスカーソルを移動したりせずに

マウスのボタンを離した → この時にイベント発生!

やっぱり。
離した時に判定されていました。

マウスの場合、ボタンを押してから移動するドラッグ操作の可能性もあるので、押した瞬間クリックしたとは判定できないということでしょう。

今回の場合それが仇となっています。

プレイヤーが「叩け!」とマウスボタンを押した瞬間、ゲームは反応を返さず、その後マウスボタンを離した瞬間に判定していたのです。
もちろん、マウスカーソルを少しでも移動した場合、クリック不成立で判定されません。

メニューを選択する時、このクリック判定は正しく動作するのですが、0.x 秒を争うアクションゲームであれば、このマウス判定タイミング、やはり納得がいきません。

脳で判断し、ボタンを押す時間が 0.1 秒だとしても、そこから離すまでに 0.3 秒かかっていた場合、結局0.4 秒も判断にかかった、ということになるのですから…。
気のせいだろう、とするにはさすがに大きなラグ(時間差)です。

もちろん、unity には「押した瞬間」に反応するイベントも用意されていました。

public class CollisionPlayer : MonoBehaviour, IPointerDownHandler
{
    void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
    {
    }
}

IPointerDownHandler

似ていますが、こちらはマウスを押した瞬間に判定してくれるイベントです。

メニューやドラッグ操作込みのケースであればこのイベントを使うと色々問題が起こりそうですが、このゲームの場合はとても快適に機能してくれます

ようやくこれで、マウスでも快適にプレイできるようになりました。

IPointerDownHandler を知ってはいましたが、今回のような問題に行きつくまでほぼ IPointerDownHandler = IPointerClickHandler だと思っておりました…。

さいごに

ゲームの反応が悪い、もっさりしているという理由は何もフレームレートのみに起因するわけではなく、操作周りの仕様・コーディングによってもだいぶ変わる、というお話でした。

最近のゲームであれば、インターネット環境の問題もありますし、Bluetooth で無線接続しているコントローラのせい…ってこともあるでしょう。(今回は違いましたが)
「もっさり」に至る理由は、近年より複雑化していると言えそうです。

話としては細かい部分でしたが、ゲーム性を上げる大切な部分、実はこういうところにあると思います。
気づけたのでよかったです。

満足した顔