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
49 lines
1.3 KiB
GDScript
Executable File
49 lines
1.3 KiB
GDScript
Executable File
extends Area3D
|
|
|
|
@export var poi_name: String = "Ruinen"
|
|
|
|
@onready var sprite: AnimatedSprite3D = $AnimatedSprite3D
|
|
@onready var name_label: Label3D = $Billboard/NameLabel
|
|
@onready var prompt: Label3D = $Billboard/InteractionPrompt
|
|
|
|
var player_nearby: bool = false
|
|
var visited: bool = false
|
|
|
|
func _ready() -> void:
|
|
prompt.visible = false
|
|
prompt.text = "[F] Interact"
|
|
_update_visuals()
|
|
body_entered.connect(_on_body_entered)
|
|
body_exited.connect(_on_body_exited)
|
|
|
|
func _update_visuals() -> void:
|
|
if visited:
|
|
name_label.text = poi_name
|
|
# Normale Farbe
|
|
sprite.modulate = Color(1.0, 1.0, 1.0, 1.0)
|
|
name_label.modulate = Color(1.0, 1.0, 1.0, 1.0)
|
|
else:
|
|
name_label.text = "???"
|
|
# Ausgegraut
|
|
sprite.modulate = Color(0.4, 0.4, 0.4, 1.0)
|
|
name_label.modulate = Color(0.6, 0.6, 0.6, 1.0)
|
|
|
|
func _on_body_entered(body: Node3D) -> void:
|
|
if body.is_in_group("player"):
|
|
player_nearby = true
|
|
prompt.text = "[F] Interact"
|
|
prompt.visible = true
|
|
|
|
func _on_body_exited(body: Node3D) -> void:
|
|
if body.is_in_group("player"):
|
|
player_nearby = false
|
|
prompt.visible = false
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if player_nearby and Input.is_action_just_pressed("interact"):
|
|
# Beim ersten Besuch entdecken
|
|
if not visited:
|
|
visited = true
|
|
_update_visuals()
|
|
InteractionManager.open_poi(self)
|