godot-ball-physics-movement/scripts/camera_targeter.gd
2026-02-08 17:04:26 +09:00

75 lines
2.0 KiB
GDScript

extends Camera3D
## ターゲットとなるNode3Dオブジェクト
@export var target: Node3D
## カメラの回転感度
@export var mouse_sensitivity: float = 0.003
## ターゲットからの距離
@export var distance: float = 5.0
## 最小・最大距離
@export var min_distance: float = 2.0
@export var max_distance: float = 20.0
## ズーム速度
@export var zoom_speed: float = 0.5
## 縦方向の回転制限(ラジアン)
@export var min_pitch: float = -PI / 2 + 0.1
@export var max_pitch: float = PI / 2 - 0.1
## マウスボタン(右クリックでカメラ操作)
@export var rotate_button: MouseButton = MOUSE_BUTTON_RIGHT
# 内部変数
var _yaw: float = 0.0 # 水平回転
var _pitch: float = 0.0 # 垂直回転
var _is_rotating: bool = false
func _ready() -> void:
# 初期角度を設定
if target:
var direction = global_position - target.global_position
_yaw = atan2(direction.x, direction.z)
_pitch = asin(direction.y / direction.length())
func _unhandled_input(event: InputEvent) -> void:
# マウスボタンの押下/離す
if event is InputEventMouseButton:
if event.button_index == rotate_button:
_is_rotating = event.pressed
# マウスホイールでズーム
elif event.button_index == MOUSE_BUTTON_WHEEL_UP:
distance = clamp(distance - zoom_speed, min_distance, max_distance)
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
distance = clamp(distance + zoom_speed, min_distance, max_distance)
# マウス移動で回転
elif event is InputEventMouseMotion and _is_rotating:
_yaw -= event.relative.x * mouse_sensitivity
_pitch += event.relative.y * mouse_sensitivity
_pitch = clamp(_pitch, min_pitch, max_pitch)
func _process(_delta: float) -> void:
if not target:
return
# 球面座標系でカメラ位置を計算
var offset = Vector3(
cos(_pitch) * sin(_yaw),
sin(_pitch),
cos(_pitch) * cos(_yaw)
) * distance
# カメラ位置を設定
global_position = target.global_position + offset
# ターゲットを見る
look_at(target.global_position, Vector3.UP)