[GodotEngine]3Dカメラとカメラジンバル


Godot Engine 3.xにおいて、3Dプラットフォーマーを作る際に、毎回同じことばっかりやってて思い出すのがしんどいのでメモ。

カメラ

自分はカメラを作る際に、二通りの方法で作ることが多い。
プレイヤーシーンに含めちゃう方法プレイヤーと別でカメラを用意する方法

前者はカメラの追従処理を考えなくていいのでスタンダードな方法。
後者はカメラ追従処理が必要だけど、カメラ単品を動かしやすいので汎用性高いように感じる。

カメラジンバル

ひとまず、いずれにせよCameraControllerという親ノード(Spatial)を作る。
その子ノードをh、孫ノードにv、それぞれSpatialノード。
曾孫ノードにCameraPosという名前でPosition3Dを作成。

これで、hノードをY軸回転させればカメラはキャラの周囲を回る。
同様にvノードをX軸回転させればカメラはキャラの上下を回る。

カメラのズームイン・ズームアウトしたい場合は、CameraPosのローカルZ座標を動かせばOK。

CameraController.gd
export var _distance:float = 3.0
export var _vertical_rotate:float = -20.0

onready var _camera_gimbal_h:Spatial = get_node("h")
onready var _camera_gimbal_v:Spatial = get_node("h/v")
onready var _camera_position:Spatial = get_node("h/v/CameraPos")

func _ready():
	_camera_pos_node.translation.z = distance
	_camera_gimbal_v.rotate_x(deg2rad(vertical_rotate))

インスペクターで好きな角度や距離を設定しておけば、ゲーム開始時にその値で開始される。
toolキーワードを付けておいてEngine.editor_hintで設定してもいいかも。

https://docs.godotengine.org/ja/stable/tutorials/plugins/running_code_in_the_editor.html

カメラは、プレイヤーシーンに入れるにしても入れないにしても、CameraPosノードの座標を見て_process(_delta)で動かすようにすれば良い。
_physics_process(_delta)で動かすと物理プロセス側(衝突処理が多いとか)でラグが起きるとカメラに影響して画面全体がカクつく原因になるので、分けておくのが良いみたい。

SpringArmノードを使うのもあり。
ただ個人的には、SpringArmを使うと障害物がある場合にキャラクターに寄っていってしまう挙動よりもコ○ミ社が特許(2016年に失効)を持っていた、カメラとターゲットの間のオブジェクトの半透明化のほうが好きなので、SpringArmは使っていない。