Godot キャラコン 06 「マウスカーソルがゲーム画面から出ないように」
マウスカーソルがゲーム画面から出ると、ヘッドコントロールが出来なくなるので、これをどうにかする。ただ、ゲーム画面からマウスカーソルが出れないと窓の[×]ボタンでゲームを終了させられなくなるため、併せて終了処理も追加する。あとカメラもくっ付ける。
マウスカーソル
Godotでは、マウスカーソルの状態を4つに変化させることが出来るようだ。MouseMode(マウスモード)と言うらしい。それぞれが名前だけでなく、数値(定数)も持っている。Input
クラスで定義されている。
マウスモード | 数値 | マウスカーソルの状態 |
---|---|---|
MOUSE_MODE_VISIBLE | 0 | 表示 |
MOUSE_MODE_HIDDEN | 1 | 非表示 |
MOUSE_MODE_CAPTURED | 2 | 非表示かつゲーム画面から出ないようにする |
MOUSE_MODE_CONFINED | 3 | 説明がないので分からんバイ |
今回まったくちょうどいい事に、このマウスモードのMOUSE_MODE_CAPTUREDが使える。スクリプトは、プレイヤのものに追加していくとゴチャゴチャするので、ルートノードに貼る事にする。
中身はたったのこれだけ。
L4
- マウスモードのセットは
set_mouse_mode()
関数を使うだけ。 - 注意点は、関数もモードも
Input
クラスで定義されているものなので、両方ともInput.
を付け忘れない事。
L8~9
- マウスカーソルがゲーム画面から出られないので、×も押せないし、[シーン停止]ボタンも押せない。つまり、ゲームを終了させる手段がなくなる。
- そこで、ここではESCキーが押されたら、ゲームを終了させる処理を追加している。
is_action_just_pressed()
は押した時、1回だけ反応するもの。押しっぱなしでも判定は1回だけ。それに対し、is_action_pressed()
は押しっぱなしの時はズット反応する。- アクション"ui_cancel"はデフォでESCキーに割り当てられているもの。そのまま利用させてもらった。
get_tree().quit()
でゲームを終了させる。
カメラをヘッドの子に
プレイヤの動きも、まーまーイイ感じに動くので、そろそろカメラをヘッドの子としてくっつける。D&Dで移動させるだけ。
ただ、Translationは整えること。
それから、今までカメラに見立てたメッシュを置いていたが、消してもいいし、非表示にしてもいいし、このままほっといてもいい。そのまま置いておいても、カメラはメッシュの裏側から撮影するので、どうせ描写されない。
適当にオブジェクト(メッシュ)を配置して
何にも無いとどっちに進んでいるのか分からないので、適当にオブジェを置く。
もちろん、シーンパネル上での見た目がゴチャゴチャしないように、フォルダ用途のノードにぶらさげる。
[シーン再生]で動かすと、これでなんとかTPSっぽくなるが、なんかカクカクするんだよなー。
特に、キーを押しながらマウスを動かすと、かなりおかしいよね。
マウスセンシを下げると、更におかしさ倍増。
よく分からんけど・・・
たぶん、マウスの動きがちゃんと反映されていないんでは? と思った。_Input(event)
と_physics_process(delta)
のタイミングは違うよねキット。
ということで、前に、もしかしたら・・・かもという予感がしてたから記事にしたんだけど、その部分をスクリプトに反映してみた。そしたら、やや改善した感じ。やっぱり俺のカンは正しかった!?
キャラコン02の、この部分ね。
もしかしたら、2行目、
my_mou_rel += event.relative
かもな?
ということで、プレイヤにつけたスクリプトの_Input(event)
関数のボディを変更。
ま、"="が"+="になるだけね。といっても、やってることは全然違うけどな。これで、_physics_process(delta)
に行く前のマウスの動きが、すべて残さず加算される事になるはず。
まだカクカクするような気もするけど。
カメラの動きはやっぱりカメラノードに貼って、_process(delta)
で動かしてと言う感じに、分けるべきだったかなー。どこかでいつか分けるかも。今のところはこれで。
コピペ用: マウスが画面から出ないようにするやつ
extends Node func _ready(): Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) pass func _process(delta): if Input.is_action_just_pressed("ui_cancel"): get_tree().quit()
あー、pass
っていらなかったな。いまさら・・・。