Godot 4.6 exploration game with player movement, step-rotation camera rig, and POI interaction system (explore/rest/close menu). main.tscn is a test scene with placeholder props; debug/ holds unwired terrain prototypes (voxel river, procedural island mesh, cross-shaped hub
78 lines
2.7 KiB
GDScript
Executable File
78 lines
2.7 KiB
GDScript
Executable File
extends Node3D
|
|
|
|
@export var target: NodePath # Player-Pfad hier im Inspector setzen!
|
|
@export var rotation_step: float = 45.0 # 360/8 Steps
|
|
@export var rotation_speed: float = 3.0 # Smooth-Rotation
|
|
@export var zoom_min: float = 4.0
|
|
@export var zoom_max: float = 20.0
|
|
@export var zoom_step: float = 1.5
|
|
@export var mouse_sensitivity: float = 0.3
|
|
|
|
var _target_node: Node3D
|
|
var _current_zoom: float = 10.0
|
|
var _target_rotation_y: float = 0.0
|
|
var _mouse_rotating: bool = false
|
|
|
|
@onready var arm: Node3D = $CameraArm
|
|
@onready var camera: Camera3D = $CameraArm/Camera3D
|
|
|
|
func _ready() -> void:
|
|
_target_node = get_node(target)
|
|
_current_zoom = camera.position.z
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
# Maus-Scroll Zoom
|
|
if event is InputEventMouseButton:
|
|
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
|
_current_zoom = clamp(_current_zoom - zoom_step, zoom_min, zoom_max)
|
|
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
|
_current_zoom = clamp(_current_zoom + zoom_step, zoom_min, zoom_max)
|
|
# Rechte Maustaste für Maus-Kamerarotation
|
|
elif event.button_index == MOUSE_BUTTON_RIGHT:
|
|
_mouse_rotating = event.pressed
|
|
Input.set_mouse_mode(
|
|
Input.MOUSE_MODE_CAPTURED if _mouse_rotating else Input.MOUSE_MODE_VISIBLE
|
|
)
|
|
|
|
# Maus-Bewegung → Kamera-Rotation
|
|
if event is InputEventMouseMotion and _mouse_rotating:
|
|
_target_rotation_y -= event.relative.x * mouse_sensitivity
|
|
|
|
func _process(delta: float) -> void:
|
|
if not _target_node:
|
|
return
|
|
|
|
# Kamera folgt Player (Position)
|
|
#global_position = global_position.lerp(_target_node.global_position, 10.0 * delta)
|
|
global_position = _target_node.global_position # Kein Lerp, exakt folgen
|
|
|
|
# Step-Rotation (Q/E + LB/RB)
|
|
if Input.is_action_just_pressed("cam_rotate_left"):
|
|
_target_rotation_y += rotation_step
|
|
if Input.is_action_just_pressed("cam_rotate_right"):
|
|
_target_rotation_y -= rotation_step
|
|
|
|
# Rechter Stick X → kontinuierliche Rotation
|
|
# var stick_x = Input.get_axis("", "") # → siehe Hinweis unten
|
|
# Füge in Input Map "cam_rotate_analog_left/right" für Stick hinzu
|
|
# var stick_x = Input.get_axis("cam_rotate_analog_left", "cam_rotate_analog_right")
|
|
# _target_rotation_y -= stick_x * rotation_speed * delta * 100
|
|
|
|
# Controller Trigger Zoom
|
|
var zoom_in_val = Input.get_action_strength("zoom_in")
|
|
var zoom_out_val = Input.get_action_strength("zoom_out")
|
|
_current_zoom = clamp(
|
|
_current_zoom - (zoom_in_val - zoom_out_val) * zoom_step * delta * 5,
|
|
zoom_min, zoom_max
|
|
)
|
|
|
|
# Rotation smoothen
|
|
rotation_degrees.y = lerp_angle(
|
|
deg_to_rad(rotation_degrees.y),
|
|
deg_to_rad(_target_rotation_y),
|
|
rotation_speed * delta
|
|
) * (180.0 / PI)
|
|
|
|
# Zoom anwenden
|
|
camera.position.z = lerp(camera.position.z, _current_zoom, 10.0 * delta)
|