Godot キャラコン 03 「カメラぐるぐる 2/2」...縦
「横ぐるぐるが」出来たので、今度は縦にうなづけるようにする。じゃ~「縦うんうん」か。で、注意点としては、ノード自身が持っている軸(ローカル軸)で回すのと、回す際、際限なく回すのではなく、±80度などの限度をつけること。この2点に注意してスクリプトしていく。(本当は回してないんだけどね。)
うなづきスクリプト
先に貼るぜ。スクリプトの追加部分は2ヶ所な。丁寧な解説は以下。
[1]
var my_head_ang = 0.0 # head virtical angle var my_head_ang_max = PI / 3.0 # head max virtical angle (60 deg)
1行目
- ヘッドのうなづきアングルを入れる変数の設定。ヘッドの縦角度を入れ、上下に傾き過ぎないようチェックするためのもの。角度はラジアンで入る。
- "0.0"とここで数値を入れているが、もっと安全にやりたかったら、
_ready()
関数内でヘッドのx軸の回転角度を入れるようにすればいい。ま、普通に置いた場合は"0"だから、こうしたケド。
2行目
- ヘッドの傾き限界角の設定。さっきも注意点として挙げたけど、普通は縦方向に360度ぐるぐる回るようにはしないよね。カメラがひっくり返らないように、傾く限度を設ける。ラジアンで設定。
- 今回は計算が楽なので、±60度内で動いてもらうよう、限度は60度に設定。前にも出て来たけど、
PI
はGodotが決めた値(定数)で180度を表すラジアンだったよね。3で割ってるから、角度的には60度ね。
[2]
# virtical my_head_ang = my_head_ang - my_mou_rel.y * my_mou_sen my_head_ang = clamp(my_head_ang, -my_head_ang_max, my_head_ang_max) my_head.rotation.x = my_head_ang
1行目はコメント。virtical(発:バーティカル、意:垂直の、縦の)。ちなみにhorizontal(発:ホリゾンタル、意:水平の、横の)。
2行目
- マウスが縦方向に動いた分(
my_mou_rel.y
)、現状のヘッド角から減算。マウスセンシを掛け忘れるなよ。 - 減算するか加算するかは、お好みで。フライトシミュみたいにしたかったら加算すれば。
- 普通は、上下左右の操作を反転できるようにインバートの変数を設けるけど、今回はめんどいのでナシだ。
3行目
clamp()
関数は便利すぎるから絶対覚えよう。ちなみに黄色いからGodotの内蔵関数って分かるよね。
clamp(変数, 下限, 上限)
のように指定して、変数の値が「下限~上限」の間から出ないようにしてくれる。ま、出ないようにというか、出たら、それぞれ上限値・下限値になるってこと。
- 今回だったら、ヘッドのうなづきアングル("my_head_ang")は±60度内に限定したいじゃん。でもマウスが動いた分、先にザックリ引いちゃってる。そうすると、場合によっては既に限度からはみ出してるかもだろ。だから、これを使って、はみ出した部分は無視してもらうってこと。
- clamp(発:クランプ、意:締め金、~を留める)。締め金って何かよく分かんないけど、数値が「下限~上限」の中に留まるようにするってことだな、きっと。
4行目
- ヘッドのうなづき角は±60度(もちろん変数はラジアンで入ってるぞ)になってる。それをヘッドのx軸に入れる。
- "my_head.rotation.x"で、ヘッドのローカル軸xの数値を直接いじるぜ。さらっと言ってるけど、よく分からない時はAPIを確認してくれよな。Spatialくらすの変数。
- 関数を使って回すのではなく、数値を入れてる。せっかく数値を限ったんだから、ズバリそれをセットして使えばいいよね。グローバルで回しちゃダメだぜ。
確認
これで、横にも縦にも思い通り動くはず。シーン再生じゃ。
まだ、マウスカーソルがゲーム画面を出たらダメだけどな。
あー、今回コメントは、万一、外人さんがコードを見たとき分かりやすいかな~って思って英語にしてみたけど(コードの一部分だけコピペしてググると、俺のブログがヒットする場合があるからな~)、次回から日本語で書こうかな。間違った英語だったら、逆に意味不明だしな。
コピペ用
extends KinematicBody # mouse var my_mou_sen = 0.01 # mouse sensitivity var my_mou_rel = Vector2(0, 0) # mouse relative # head (camera pivot) var my_head # head node var my_head_ang = 0.0 # head virtical angle var my_head_ang_max = PI / 3.0 # head max virtical angle (60 deg) func _ready(): my_head = get_node("Spatial_Head") func _input(event): if event is InputEventMouseMotion: my_mou_rel = event.relative func _physics_process(delta): # head movement # horizontal my_head.global_rotate(Vector3(0, 1, 0), -my_mou_rel.x * my_mou_sen) # virtical my_head_ang = my_head_ang - my_mou_rel.y * my_mou_sen my_head_ang = clamp(my_head_ang, -my_head_ang_max, my_head_ang_max) my_head.rotation.x = my_head_ang # reset my_mou_rel = Vector2(0, 0)