俺に解るように説明する "Godot Engine 3.x" 入門+

ゲームエンジン Godot Engine に関すること。入門とか使い方とかチュートリアルとか、あれとかこれとか。日本語解説。

Godot キャラコン 06 「マウスカーソルがゲーム画面から出ないように」

マウスカーソルがゲーム画面から出ると、ヘッドコントロールが出来なくなるので、これをどうにかする。ただ、ゲーム画面からマウスカーソルが出れないと窓の[×]ボタンでゲームを終了させられなくなるため、併せて終了処理も追加する。あとカメラもくっ付ける。
f:id:ore2wakaru:20180404232210g:plain


マウスカーソル

Godotでは、マウスカーソルの状態を4つに変化させることが出来るようだ。MouseMode(マウスモード)と言うらしい。それぞれが名前だけでなく、数値(定数)も持っている。Inputクラスで定義されている。

マウスモード 数値 マウスカーソルの状態
MOUSE_MODE_VISIBLE 0 表示
MOUSE_MODE_HIDDEN 1 非表示
MOUSE_MODE_CAPTURED 2 非表示かつゲーム画面から出ないようにする
MOUSE_MODE_CONFINED 3 説明がないので分からんバイ

今回まったくちょうどいい事に、このマウスモードのMOUSE_MODE_CAPTUREDが使える。スクリプトは、プレイヤのものに追加していくとゴチャゴチャするので、ルートノードに貼る事にする。
f:id:ore2wakaru:20180404222709p:plain

中身はたったのこれだけ。
f:id:ore2wakaru:20180404215512p:plain

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で移動させるだけ。
f:id:ore2wakaru:20180404222841p:plain

ただ、Translationは整えること。
f:id:ore2wakaru:20180404223215p:plain

それから、今までカメラに見立てたメッシュを置いていたが、消してもいいし、非表示にしてもいいし、このままほっといてもいい。そのまま置いておいても、カメラはメッシュの裏側から撮影するので、どうせ描写されない。


適当にオブジェクト(メッシュ)を配置して

何にも無いとどっちに進んでいるのか分からないので、適当にオブジェを置く。
f:id:ore2wakaru:20180404224115p:plain

もちろん、シーンパネル上での見た目がゴチャゴチャしないように、フォルダ用途のノードにぶらさげる。
f:id:ore2wakaru:20180404233145p:plain

[シーン再生]で動かすと、これでなんとかTPSっぽくなるが、なんかカクカクするんだよなー。

特に、キーを押しながらマウスを動かすと、かなりおかしいよね。

マウスセンシを下げると、更におかしさ倍増。


よく分からんけど・・・

たぶん、マウスの動きがちゃんと反映されていないんでは? と思った。_Input(event)_physics_process(delta)のタイミングは違うよねキット。

ということで、前に、もしかしたら・・・かもという予感がしてたから記事にしたんだけど、その部分をスクリプトに反映してみた。そしたら、やや改善した感じ。やっぱり俺のカンは正しかった!?

キャラコン02の、この部分ね。

もしかしたら、2行目、
my_mou_rel += event.relative
かもな?

ということで、プレイヤにつけたスクリプト_Input(event)関数のボディを変更。
f:id:ore2wakaru:20180404230923p:plain

ま、"=""+="になるだけね。といっても、やってることは全然違うけどな。これで、_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っていらなかったな。いまさら・・・。