Initial commit: WayfarersWanderer project state

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
This commit is contained in:
Jonas Reith 2026-08-26 19:05:30 +02:00
commit fa38e603a1
45 changed files with 1978 additions and 0 deletions

4
.editorconfig Executable file
View File

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Executable file
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Executable file
View File

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

BIN
assets/debug/checkerboard.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

View File

@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c3ajv7vb8c4fb"
path.s3tc="res://.godot/imported/checkerboard.png-4dad1517039036e2382fd0e75874c867.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/debug/checkerboard.png"
dest_files=["res://.godot/imported/checkerboard.png-4dad1517039036e2382fd0e75874c867.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

BIN
assets/models/forest.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://be2uq7ixlbv6b"
path="res://.godot/imported/forest.glb-afdae727313ccf3677ce0399e0a685a4.scn"
[deps]
source_file="res://assets/models/forest.glb"
dest_files=["res://.godot/imported/forest.glb-afdae727313ccf3677ce0399e0a685a4.scn"]
[params]
nodes/root_type="StaticBody3D"
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,44 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://2lcgru3xuc8"
path.s3tc="res://.godot/imported/forest_tree_greenv1.png-41eb1d87b8c434eab69a5036447034b0.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
generator_parameters={
"md5": "2a028cc382b673f5e99d7e8ee1469ea2"
}
[deps]
source_file="res://assets/models/forest_tree_greenv1.png"
dest_files=["res://.godot/imported/forest_tree_greenv1.png-41eb1d87b8c434eab69a5036447034b0.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

BIN
assets/models/mountain.glb Normal file

Binary file not shown.

View File

@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dmhs1oy1kh6hi"
path="res://.godot/imported/mountain.glb-8b287651a1bb38426cf17e1af324657c.scn"
[deps]
source_file="res://assets/models/mountain.glb"
dest_files=["res://.godot/imported/mountain.glb-8b287651a1bb38426cf17e1af324657c.scn"]
[params]
nodes/root_type="StaticBody3D"
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

Binary file not shown.

View File

@ -0,0 +1,42 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://gl4qpk4wto1e"
path="res://.godot/imported/mountain2v5.glb-cc550bf83dc570ce62fc6eaf2007f3e5.scn"
[deps]
source_file="res://assets/models/mountain2v5.glb"
dest_files=["res://.godot/imported/mountain2v5.glb-cc550bf83dc570ce62fc6eaf2007f3e5.scn"]
[params]
nodes/root_type="StaticBody3D"
nodes/root_name=""
nodes/root_script=null
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c0u8xjymrfw2x"
path.s3tc="res://.godot/imported/Brown-gray_ruins2.png-84005ae1fb5515afcbec8705a5b236e9.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/sprites/enviroment/Brown-gray_ruins2.png"
dest_files=["res://.godot/imported/Brown-gray_ruins2.png-84005ae1fb5515afcbec8705a5b236e9.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://epcqli428yem"
path.s3tc="res://.godot/imported/debug_player.png-3f02112dbaffc1fe27016269e0bd44e1.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://assets/sprites/player/debug_player.png"
dest_files=["res://.godot/imported/debug_player.png-3f02112dbaffc1fe27016269e0bd44e1.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

77
camera_rig.gd Executable file
View File

@ -0,0 +1,77 @@
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)

1
camera_rig.gd.uid Executable file
View File

@ -0,0 +1 @@
uid://b0y06y7c0bihj

34
debug/FreeCam.gd Normal file
View File

@ -0,0 +1,34 @@
extends Node3D
@export var fly_speed : float = 20.0
@export var fast_speed : float = 60.0
@export var sensitivity: float = 0.003
var yaw : float = PI
var pitch : float = -0.38
var captured: bool = false
func _unhandled_input(e: InputEvent) -> void:
if e is InputEventMouseButton and e.button_index == MOUSE_BUTTON_RIGHT:
captured = e.pressed
Input.set_mouse_mode(
Input.MOUSE_MODE_CAPTURED if captured else Input.MOUSE_MODE_VISIBLE)
if e is InputEventMouseMotion and captured:
yaw -= e.relative.x * sensitivity
pitch = clamp(pitch - e.relative.y * sensitivity, -1.4, 0.2)
rotation = Vector3(pitch, yaw, 0)
if e is InputEventKey and e.pressed and e.keycode == KEY_ESCAPE:
captured = false
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
func _process(delta: float) -> void:
var spd := fast_speed if Input.is_key_pressed(KEY_SHIFT) else fly_speed
var move := Vector3.ZERO
if Input.is_key_pressed(KEY_W): move -= global_transform.basis.z
if Input.is_key_pressed(KEY_S): move += global_transform.basis.z
if Input.is_key_pressed(KEY_A): move -= global_transform.basis.x
if Input.is_key_pressed(KEY_D): move += global_transform.basis.x
if Input.is_key_pressed(KEY_E): move += Vector3.UP
if Input.is_key_pressed(KEY_Q): move -= Vector3.UP
if move.length_squared() > 0:
position += move.normalized() * spd * delta

1
debug/FreeCam.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://bia8axed2ndwj

271
debug/Grenze.gd Normal file
View File

@ -0,0 +1,271 @@
extends Node3D
@export var berg_scale : float = .002
# Welt-Parameter
const ISLAND_RADIUS : float = 512.0
const GRID : float = 1.0 # 1m pro Block
const CORRIDOR_WIDTH : int = 3 # Korridor-Breite in Blöcken
const CENTER_RADIUS : float = 120.0 # Radius Mittelzone
# Pass-Position: Anteil vom Rand der Mittelzone (0=Mitte, 1=Inselrand)
# 0.35 = ca. erstes Drittel ab Mittelzone Richtung Rand
const PASS_POS : float = 0.35
const PASS_WIDTH : int = 3 # Lücke in Blöcken
func _ready() -> void:
_spawn_kreuz()
_spawn_mittelring()
_spawn_ozean()
# ═══════════════════════════════════════════════════════════════
# KREUZ — 4 Arme: Nord, Süd, West = Berge | Ost = Fluss
# ═══════════════════════════════════════════════════════════════
func _spawn_kreuz() -> void:
# Jeder Arm geht von CENTER_RADIUS bis ISLAND_RADIUS
_spawn_arm_berge("Nord", Vector3( 0, 0, -1))
_spawn_arm_berge("Sued", Vector3( 0, 0, 1))
_spawn_arm_berge("West", Vector3(-1, 0, 0))
_spawn_arm_fluss("Ost", Vector3( 1, 0, 0))
# ── Berg-Arm ─────────────────────────────────────────────────
func _spawn_arm_berge(label: String, dir: Vector3) -> void:
var grp := Node3D.new()
grp.name = "Arm_" + label
add_child(grp)
var perp := dir.cross(Vector3.UP).normalized()
var arm_len := ISLAND_RADIUS - CENTER_RADIUS
var steps := int(arm_len / GRID)
# Pass-Bereich berechnen (in Steps ab Mittelzone)
var pass_start := int(steps * PASS_POS)
var pass_end := pass_start + PASS_WIDTH
# Große Berg-Modelle vorbauen
var large_meshes := _make_large_berge()
var small_meshes := _make_small_berge()
for step in range(steps):
# Position entlang des Arms
var dist := CENTER_RADIUS + step * GRID + GRID * 0.5
var center := dir * dist
var in_pass := (step >= pass_start and step < pass_end)
for col in range(-CORRIDOR_WIDTH / 2, CORRIDOR_WIDTH / 2 + 1):
var pos := center + perp * (col * GRID)
pos.y = 0.0
if in_pass:
# Im Pass: nur außen kleine Berge, Mitte frei
if abs(col) == CORRIDOR_WIDTH / 2:
_place_berg(grp, pos, small_meshes)
# col == 0 → frei (Durchgang)
else:
# Außenreihen → kleine Berge dicht
if abs(col) >= 1:
_place_berg(grp, pos, small_meshes)
# Mittelreihe → große Berge
else:
_place_berg(grp, pos, large_meshes)
# Pass-Marker (Platzhalter Tor)
var pass_dist := CENTER_RADIUS + (pass_start + PASS_WIDTH * 0.5) * GRID
var pass_center := dir * pass_dist
_spawn_pass_marker(grp, pass_center)
func _place_berg(parent: Node3D, pos: Vector3, meshes: Array) -> void:
var mi := MeshInstance3D.new()
mi.mesh = meshes[randi() % meshes.size()]
mi.position = pos
# Zufällige Y-Rotation für Abwechslung
mi.rotation.y = randf() * TAU
parent.add_child(mi)
# ── Fluss-Arm ────────────────────────────────────────────────
func _spawn_arm_fluss(label: String, dir: Vector3) -> void:
var grp := Node3D.new()
grp.name = "Arm_" + label
add_child(grp)
var arm_len := ISLAND_RADIUS - CENTER_RADIUS
var steps := int(arm_len / GRID)
var pass_start := int(steps * PASS_POS)
var pass_end := pass_start + PASS_WIDTH
var mat_wasser := StandardMaterial3D.new()
mat_wasser.albedo_color = Color(0.18, 0.45, 0.78)
mat_wasser.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
for step in range(steps):
var dist := CENTER_RADIUS + step * GRID + GRID * 0.5
var pos := dir * dist
pos.y = -0.5 # 1m tief eingeschnitten
var in_pass := (step >= pass_start and step < pass_end)
if in_pass:
# Brücken-Block
_spawn_bruecke_block(grp, dir * dist)
else:
# Fluss-Block: 1x1m Wasser
var mi := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = Vector3(GRID, GRID, GRID)
box.surface_set_material(0, mat_wasser)
mi.mesh = box
mi.position = pos
mi.name = "Fluss_" + str(step)
grp.add_child(mi)
func _spawn_bruecke_block(parent: Node3D, pos: Vector3) -> void:
var mi := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = Vector3(GRID * 3.0, 0.3, GRID * 3.0)
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.55, 0.45, 0.32)
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
box.surface_set_material(0, mat)
mi.mesh = box
mi.position = pos + Vector3(0, 0.65, 0)
mi.name = "Bruecke"
parent.add_child(mi)
# ── Pass-Marker ───────────────────────────────────────────────
func _spawn_pass_marker(parent: Node3D, pos: Vector3) -> void:
var mi := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = Vector3(2.0, 4.0, 2.0)
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.85, 0.78, 0.40)
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
box.surface_set_material(0, mat)
mi.mesh = box
mi.position = pos + Vector3(0, 2.0, 0)
mi.name = "PassMarker"
parent.add_child(mi)
# ═══════════════════════════════════════════════════════════════
# MITTELRING — Bergring um die Mittelzone
# ═══════════════════════════════════════════════════════════════
func _spawn_mittelring() -> void:
var grp := Node3D.new()
grp.name = "Mittelring"
add_child(grp)
var large_meshes := _make_large_berge()
var small_meshes := _make_small_berge()
# Umfang des Kreises in 1m-Schritten
var circumference := TAU * CENTER_RADIUS
var steps := int(circumference / GRID)
# Die 4 Kreuz-Arme blockieren bestimmte Winkel → dort Pässe
# Arm-Winkel: Nord=270°, Süd=90°, West=180°, Ost=0°
var arm_angles := [0.0, PI * 0.5, PI, PI * 1.5]
var pass_half := (float(PASS_WIDTH) * GRID) / CENTER_RADIUS # Winkel-Halbbreite
for step in range(steps):
var angle := float(step) / steps * TAU
# Prüfen ob dieser Winkel in einem Arm-Durchgang liegt
var in_arm := false
for arm_a in arm_angles:
var diff: float = abs(angle_difference(angle, arm_a))
if diff < pass_half * 1.5:
in_arm = true
break
# Innenring (dicht am Center_radius)
var r_inner := CENTER_RADIUS - 1.0
var pos_i := Vector3(cos(angle)*r_inner, 0, sin(angle)*r_inner)
# Außenring
var r_outer := CENTER_RADIUS + 2.0
var pos_o := Vector3(cos(angle)*r_outer, 0, sin(angle)*r_outer)
if not in_arm:
_place_berg(grp, pos_i, large_meshes)
_place_berg(grp, pos_o, small_meshes)
# Hilfsfunktion: Winkel-Differenz -PI..PI
func angle_difference(a: float, b: float) -> float:
var d := fmod(a - b + TAU, TAU)
if d > PI: d -= TAU
return d
# ═══════════════════════════════════════════════════════════════
# BERG-MODELLE — prozedural, mehrere Varianten
# ═══════════════════════════════════════════════════════════════
func _make_large_berge() -> Array:
var result := []
# 4 große Varianten: breiter, massiver
var configs := [
[8.0, 0.05, 22.0, 6],
[10.0, 0.05, 18.0, 7],
[7.0, 0.05, 26.0, 5],
[12.0, 0.05, 20.0, 8],
]
for cfg in configs:
result.append(_make_berg_mesh(cfg[0], cfg[1], cfg[2] * berg_scale, int(cfg[3]), false))
return result
func _make_small_berge() -> Array:
var result := []
# 6 kleine Varianten: schmaler, dichter packbar
var configs := [
[3.0, 0.02, 10.0, 5],
[2.5, 0.02, 8.0, 6],
[4.0, 0.02, 12.0, 5],
[2.0, 0.02, 7.0, 4],
[3.5, 0.02, 11.0, 6],
[2.8, 0.02, 9.0, 5],
]
for cfg in configs:
result.append(_make_berg_mesh(cfg[0], cfg[1], cfg[2], int(cfg[3]), true))
return result
func _make_berg_mesh(bot_r: float, top_r: float, h: float,
sides: int, small: bool) -> Mesh:
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
var tip := Vector3(0, h, 0)
var gray := randf_range(0.35, 0.55) if not small else randf_range(0.40, 0.58)
var col := Color(gray, gray * 0.97, gray * 0.93)
var col_b := Color(gray * 0.7, gray * 0.68, gray * 0.65)
for s in range(sides):
var a0 := float(s) / sides * TAU
var a1 := float(s+1) / sides * TAU
var b0 := Vector3(cos(a0)*bot_r, 0, sin(a0)*bot_r)
var b1 := Vector3(cos(a1)*bot_r, 0, sin(a1)*bot_r)
var t0 := Vector3(cos(a0)*top_r, h, sin(a0)*top_r)
var t1 := Vector3(cos(a1)*top_r, h, sin(a1)*top_r)
# Seite
var n := (b1 - b0).cross(tip - b0).normalized()
st.set_normal(n); st.set_color(col)
st.add_vertex(b0); st.add_vertex(tip); st.add_vertex(b1)
# Boden-Cap
st.set_normal(Vector3(0,-1,0)); st.set_color(col_b)
st.add_vertex(Vector3(0,0,0)); st.add_vertex(b1); st.add_vertex(b0)
return st.commit()
# ═══════════════════════════════════════════════════════════════
# OZEAN unter der Insel
# ═══════════════════════════════════════════════════════════════
func _spawn_ozean() -> void:
var mi := MeshInstance3D.new()
var plane := PlaneMesh.new()
plane.size = Vector2(4096, 4096)
var mat := StandardMaterial3D.new()
mat.albedo_color = Color(0.08, 0.25, 0.52)
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
plane.surface_set_material(0, mat)
mi.mesh = plane
mi.position = Vector3(0, -40, 0)
mi.name = "Ozean"
add_child(mi)

1
debug/Grenze.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://cql864jt4i24

100
debug/IslandMesh.gd Normal file
View File

@ -0,0 +1,100 @@
extends Node3D
@export var radius : float = 1024.0
@export var segments: int = 128
@export var seed_val: int = 42
@export var erosion : float = 0.18
func _ready() -> void:
_build()
func _build() -> void:
var noise := FastNoiseLite.new()
noise.seed = seed_val
noise.noise_type = FastNoiseLite.TYPE_SIMPLEX_SMOOTH
noise.frequency = 0.008
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
var verts: PackedVector3Array = []
var colrs: PackedColorArray = []
var seg := segments
for i in range(seg + 1):
for j in range(seg + 1):
var u := float(i) / seg
var v := float(j) / seg
var angle := u * TAU
var r := v * radius
var en := 1.0 + noise.get_noise_2d(
cos(angle) * 80.0,
sin(angle) * 80.0) * erosion
var x := cos(angle) * r * en
var z := sin(angle) * r * en
var dn := r / radius
# Komplett flach — nur Rand fällt ab
var y := -6.0 * pow(dn, 6.0)
verts.append(Vector3(x, y, z))
colrs.append(_col(dn))
for i in range(seg):
for j in range(seg):
var idx := i * (seg + 1) + j
var a := idx; var b := idx + 1
var c := idx+(seg+1); var d := idx+(seg+1)+1
var n := (verts[b]-verts[a]).cross(verts[c]-verts[a]).normalized()
for vtx in [a, b, c]:
st.set_normal(n); st.set_color(colrs[vtx])
st.add_vertex(verts[vtx])
for vtx in [b, d, c]:
st.set_normal(n); st.set_color(colrs[vtx])
st.add_vertex(verts[vtx])
var mesh := st.commit()
var mat := StandardMaterial3D.new()
mat.vertex_color_use_as_albedo = true
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mesh.surface_set_material(0, mat)
var mi := MeshInstance3D.new()
mi.mesh = mesh
add_child(mi)
_build_underside()
func _col(dn: float) -> Color:
if dn > 0.93: return Color(0.45, 0.38, 0.28) # Erdrand
if dn > 0.85: return Color(0.38, 0.55, 0.25) # Gras außen
return Color(0.42, 0.65, 0.30) # Gras
func _build_underside() -> void:
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
var seg := 80
var bot := Vector3(0, -18.0, 0)
var noise := FastNoiseLite.new()
noise.seed = seed_val + 1
for i in range(seg):
var a0 := float(i) / seg * TAU
var a1 := float(i+1) / seg * TAU
var r := radius * 0.9
var e0 := 1.0 + noise.get_noise_2d(cos(a0)*80, sin(a0)*80) * erosion
var e1 := 1.0 + noise.get_noise_2d(cos(a1)*80, sin(a1)*80) * erosion
var p0 := Vector3(cos(a0)*r*e0, -2.0, sin(a0)*r*e0)
var p1 := Vector3(cos(a1)*r*e1, -2.0, sin(a1)*r*e1)
var col := Color(0.30, 0.25, 0.18)
st.set_color(col); st.set_normal(Vector3(0,-1,0))
st.add_vertex(bot); st.add_vertex(p1); st.add_vertex(p0)
# Seite
var t0 := Vector3(p0.x, 0.0, p0.z)
var t1 := Vector3(p1.x, 0.0, p1.z)
st.add_vertex(p0); st.add_vertex(t0); st.add_vertex(p1)
st.add_vertex(t0); st.add_vertex(t1); st.add_vertex(p1)
var mesh := st.commit()
var mat := StandardMaterial3D.new()
mat.vertex_color_use_as_albedo = true
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
mesh.surface_set_material(0, mat)
var mi := MeshInstance3D.new()
mi.mesh = mesh
add_child(mi)

1
debug/IslandMesh.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://d0xuftjl5xssi

22
debug/fluss_proto.tscn Normal file
View File

@ -0,0 +1,22 @@
[gd_scene format=3 uid="uid://cidsmilm68b5q"]
[ext_resource type="PackedScene" uid="uid://dljjlqptwc2a2" path="res://player.tscn" id="1_ei44b"]
[ext_resource type="Script" uid="uid://syb1gkanuju7" path="res://debug/voxel.gd" id="1_iosed"]
[ext_resource type="Script" uid="uid://bia8axed2ndwj" path="res://debug/FreeCam.gd" id="2_sjo6i"]
[node name="FlussProto" type="Node3D" unique_id=962938880]
[node name="Player" parent="." unique_id=1949521754 instance=ExtResource("1_ei44b")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.98786944, 4.5496826, 4.1674347)
[node name="Voxel" type="Node3D" parent="." unique_id=1517507308]
script = ExtResource("1_iosed")
[node name="FlyCamera2" type="Node3D" parent="." unique_id=409666653]
transform = Transform3D(1, 0, 0, 0, 0.92718387, 0.3746066, 0, -0.3746066, 0.92718387, 0, 20, 40)
script = ExtResource("2_sjo6i")
[node name="Camera3D" type="Camera3D" parent="FlyCamera2" unique_id=808390848]
fov = 65.0
near = 0.1
far = 1000.0

36
debug/flying_island.tscn Normal file
View File

@ -0,0 +1,36 @@
[gd_scene format=3 uid="uid://xes77y1x72b6"]
[ext_resource type="Script" uid="uid://bia8axed2ndwj" path="res://debug/FreeCam.gd" id="1_idwjx"]
[ext_resource type="Script" uid="uid://d0xuftjl5xssi" path="res://debug/IslandMesh.gd" id="2_obm1k"]
[ext_resource type="Script" uid="uid://cql864jt4i24" path="res://debug/Grenze.gd" id="3_3bsno"]
[sub_resource type="Environment" id="Environment_obm1k"]
background_mode = 1
background_color = Color(0.16470589, 0.25490198, 0.36078432, 1)
ambient_light_source = 2
ambient_light_color = Color(0.23529412, 0.25490198, 0.29411766, 1)
ambient_light_energy = 0.8
[node name="FlyingIsland" type="Node3D" unique_id=1133718991]
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1194180535]
environment = SubResource("Environment_obm1k")
[node name="Sun" type="DirectionalLight3D" parent="." unique_id=919416523]
transform = Transform3D(0.8660254, -0.35355338, 0.35355338, 0, 0.70710677, 0.70710677, -0.5, -0.6123724, 0.6123724, 0, 0, 0)
light_energy = 1.2
[node name="FlyCamera" type="Node3D" parent="." unique_id=86070119]
transform = Transform3D(1, 0, 0, 0, 0.92718387, 0.3746066, 0, -0.3746066, 0.92718387, 0, 60, 120)
script = ExtResource("1_idwjx")
[node name="Camera3D" type="Camera3D" parent="FlyCamera" unique_id=1353892435]
fov = 65.0
near = 0.1
far = 1000.0
[node name="IslandMesh" type="Node3D" parent="." unique_id=1416580731]
script = ExtResource("2_obm1k")
[node name="Grenze" type="Node3D" parent="." unique_id=139532892]
script = ExtResource("3_3bsno")

134
debug/voxel.gd Normal file
View File

@ -0,0 +1,134 @@
extends Node3D
const W := 10 # Breite X
const D := 10 # Tiefe Z
const H := 3 # Höhe Y
# Fluss läuft entlang Z, mittig auf X
const FLUSS_X := 5 # Welche X-Spalte (0-basiert, Mitte = 4 oder 5)
const FLUSS_TIEFE := 2 # Wie viele Blöcke von oben rausgenommen
const WASSER_Y := 0 # Y-Index wo Wasser sitzt (unterster Block des Grabens)
# Materialien — einmal erstellen, mehrfach nutzen
var mat_erde : StandardMaterial3D
var mat_gras : StandardMaterial3D
var mat_wasser : ShaderMaterial
func _ready() -> void:
_make_materials()
_build()
# ═══════════════════════════════════════════════
# MATERIALIEN
# ═══════════════════════════════════════════════
func _make_materials() -> void:
mat_erde = StandardMaterial3D.new()
mat_erde.albedo_color = Color(0.38, 0.26, 0.16)
mat_erde.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat_gras = StandardMaterial3D.new()
mat_gras.albedo_color = Color(0.35, 0.60, 0.22)
mat_gras.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
# Wasser-Shader
var shader := Shader.new()
shader.code = """
shader_type spatial;
render_mode unshaded, cull_disabled, blend_mix;
uniform vec4 color_shallow : source_color = vec4(0.2, 0.55, 0.85, 0.75);
uniform vec4 color_deep : source_color = vec4(0.1, 0.35, 0.70, 0.90);
uniform float speed : hint_range(0.0, 2.0) = 0.6;
uniform float wave_scale : hint_range(0.1, 5.0) = 1.5;
void fragment() {
vec2 uv = UV * wave_scale + vec2(TIME * speed, TIME * speed * 0.4);
float wave = sin(uv.x * 6.28) * 0.5 + 0.5;
wave += sin(uv.y * 6.28 * 1.3 + TIME * speed) * 0.3;
wave = clamp(wave * 0.5, 0.0, 1.0);
ALBEDO = mix(color_shallow.rgb, color_deep.rgb, wave);
ALPHA = mix(color_shallow.a, color_deep.a, wave);
}
"""
mat_wasser = ShaderMaterial.new()
mat_wasser.shader = shader
# ═══════════════════════════════════════════════
# WELT BAUEN
# ═══════════════════════════════════════════════
func _build() -> void:
for x in range(W):
for z in range(D):
_build_spalte(x, z)
func _build_spalte(x: int, z: int) -> void:
var ist_fluss := (x == FLUSS_X)
for y in range(H):
# Fluss-Graben: oberste FLUSS_TIEFE Blöcke fehlen
if ist_fluss and y >= (H - FLUSS_TIEFE):
continue
var mat : StandardMaterial3D
if y == H - 1 and not ist_fluss:
mat = mat_gras # Oberste Schicht = Gras
else:
mat = mat_erde # Alles darunter = Erde
_place_block(Vector3(x, y, z), mat)
# Wasser in den Graben
if ist_fluss:
var wasser_y := H - FLUSS_TIEFE # Wasser sitzt auf dem Boden des Grabens
_place_wasser(Vector3(x, wasser_y, z))
# Wasserfall: wo Fluss auf Z-Rand trifft
if ist_fluss and (z == 0 or z == D - 1):
_spawn_wasserfall(x, z)
# ═══════════════════════════════════════════════
# BLÖCKE PLATZIEREN
# ═══════════════════════════════════════════════
func _place_block(pos: Vector3, mat: StandardMaterial3D) -> void:
var mi := MeshInstance3D.new()
var box := BoxMesh.new()
box.size = Vector3(1, 1, 1)
box.surface_set_material(0, mat)
mi.mesh = box
mi.position = pos + Vector3(0.5, 0.5, 0.5) # Pivot unten-links
add_child(mi)
func _place_wasser(pos: Vector3) -> void:
var mi := MeshInstance3D.new()
var box := BoxMesh.new()
# Wasser etwas flacher als 1m damit man Tiefe sieht
box.size = Vector3(1.0, 0.65, 1.0)
box.surface_set_material(0, mat_wasser)
mi.mesh = box
mi.position = pos + Vector3(0.5, 0.33, 0.5)
mi.transparency = 0.3
add_child(mi)
# ═══════════════════════════════════════════════
# WASSERFALL
# ═══════════════════════════════════════════════
func _spawn_wasserfall(x: int, z: int) -> void:
# Vertikale Wasser-Plane von Graben-Unterkante bis Boden
var fall_h := float(H - FLUSS_TIEFE) # Höhe des Falls
var mi := MeshInstance3D.new()
var quad := QuadMesh.new()
quad.size = Vector2(1.0, fall_h)
quad.surface_set_material(0, mat_wasser)
mi.mesh = quad
# Positionierung: Außenkante der Platte
var dir_z := -1.0 if z == 0 else 1.0
mi.position = Vector3(
x + 0.5,
fall_h * 0.5, # Vertikal zentriert
z + 0.5 * dir_z # Außenkante
)
# Plane zeigt nach außen
mi.rotation.y = 0.0 if z == D - 1 else PI
add_child(mi)

1
debug/voxel.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://syb1gkanuju7

59
interaction_manager.gd Executable file
View File

@ -0,0 +1,59 @@
extends Node
signal interaction_opened
signal interaction_closed
var active: bool = false
var current_poi: Node = null
func open_poi(poi: Node) -> void:
active = true
current_poi = poi
InteractionUI.show_menu(poi.poi_name, _get_main_options())
func _get_main_options() -> Array:
return [
{ "label": "Erkunden", "action": "explore" },
{ "label": "Ausruhen", "action": "rest" },
{ "label": "Beenden", "action": "close" },
]
func handle_selection(action: String) -> void:
match action:
"explore":
InteractionUI.show_menu("Erkunden", _get_explore_options())
"rest":
InteractionUI.show_text("Du rastest eine Weile...\nDu fühlst dich erholt.")
"close":
close()
func handle_explore(action: String) -> void:
match action:
"track_follow":
var success = randf() > 0.5
if success:
InteractionUI.show_text("Du folgst den Spuren...\nEine seltene Tierbeobachtung!")
else:
InteractionUI.show_text("Du folgst den Spuren...\nDas Tier ist verschwunden.")
"track_leave":
close()
func _get_explore_options() -> Array:
# Zufälliges Ereignis beim Erkunden
var roll = randf()
if roll < 0.5:
InteractionUI.show_text("Du findest Tierspuren!")
return [
{ "label": "Tier verfolgen", "action": "track_follow" },
{ "label": "In Ruhe lassen", "action": "track_leave" },
]
else:
InteractionUI.show_text("Nichts Besonderes zu finden.")
return [
{ "label": "Zurück", "action": "close" },
]
func close() -> void:
active = false
current_poi = null
InteractionUI.hide_menu()

1
interaction_manager.gd.uid Executable file
View File

@ -0,0 +1 @@
uid://cbg1abspfwgxo

68
interaction_ui.gd Executable file
View File

@ -0,0 +1,68 @@
extends CanvasLayer
@onready var panel = $Panel
@onready var title_label = $Panel/TitleLabel
@onready var message_label = $Panel/MessageLabel
@onready var option_container = $Panel/OptionContainer
@onready var hint_label = $Panel/HintLabel
var current_options: Array = []
var selected_index: int = 0
var mode: String = "menu" # "menu" oder "text"
func _ready() -> void:
panel.visible = false
func show_menu(title: String, options: Array) -> void:
mode = "menu"
panel.visible = true
title_label.text = title
message_label.text = ""
hint_label.text = "[ESC/B] Beenden"
current_options = options
selected_index = 0
_rebuild_options()
func show_text(text: String) -> void:
mode = "text"
message_label.text = text
hint_label.text = "[F/A] Weiter [ESC/B] Beenden"
_clear_options()
func hide_menu() -> void:
panel.visible = false
current_options = []
func _rebuild_options() -> void:
_clear_options()
for i in current_options.size():
var btn = Button.new()
btn.text = current_options[i]["label"]
btn.focus_mode = Control.FOCUS_ALL
option_container.add_child(btn)
var action = current_options[i]["action"]
btn.pressed.connect(_on_option_pressed.bind(action))
# Ersten Button fokussieren
if option_container.get_child_count() > 0:
option_container.get_child(0).grab_focus()
func _clear_options() -> void:
for child in option_container.get_children():
child.queue_free()
func _on_option_pressed(action: String) -> void:
# Unterscheiden ob wir im Erkunden-Submenu sind
if action in ["track_follow", "track_leave"]:
InteractionManager.handle_explore(action)
else:
InteractionManager.handle_selection(action)
func _input(event: InputEvent) -> void:
if not panel.visible:
return
if Input.is_action_just_pressed("cancel"):
InteractionManager.close()
# Im Text-Mode mit F/A weiterklicken
if mode == "text" and Input.is_action_just_pressed("interact"):
# Zurück zum Hauptmenü
InteractionManager.open_poi(InteractionManager.current_poi)

1
interaction_ui.gd.uid Executable file
View File

@ -0,0 +1 @@
uid://dv2w4x8t53ym

57
interaction_ui.tscn Executable file
View File

@ -0,0 +1,57 @@
[gd_scene format=3 uid="uid://cmg2008xfel2v"]
[ext_resource type="Script" uid="uid://dv2w4x8t53ym" path="res://interaction_ui.gd" id="1_y37vg"]
[node name="InteractionUI" type="CanvasLayer" unique_id=1122298615]
script = ExtResource("1_y37vg")
[node name="Panel" type="Panel" parent="." unique_id=1371415037]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 0
size_flags_vertical = 8
[node name="HintLabel" type="Label" parent="Panel" unique_id=2014325289]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -308.0
offset_top = -43.0
grow_horizontal = 0
grow_vertical = 0
[node name="TitleLabel" type="Label" parent="Panel" unique_id=1341922505]
layout_mode = 1
offset_left = 40.0
offset_top = 31.0
offset_right = 716.0
offset_bottom = 54.0
size_flags_vertical = 0
[node name="OptionContainer" type="VBoxContainer" parent="Panel" unique_id=58274880]
layout_mode = 0
offset_left = 302.0
offset_top = 204.0
offset_right = 978.0
offset_bottom = 204.0
size_flags_vertical = 8
[node name="MessageLabel" type="Label" parent="Panel" unique_id=2104555059]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -38.0
offset_top = -184.0
offset_right = 299.0
offset_bottom = -161.0
grow_horizontal = 2
grow_vertical = 2

323
main.tscn Executable file
View File

@ -0,0 +1,323 @@
[gd_scene format=3 uid="uid://bju1lndv8l1mo"]
[ext_resource type="Script" uid="uid://ckrqvbqw08kin" path="res://player.gd" id="1_0xm2m"]
[ext_resource type="Texture2D" uid="uid://c3ajv7vb8c4fb" path="res://assets/debug/checkerboard.png" id="1_1bvp3"]
[ext_resource type="Texture2D" uid="uid://epcqli428yem" path="res://assets/sprites/player/debug_player.png" id="2_h2yge"]
[ext_resource type="Script" uid="uid://b0y06y7c0bihj" path="res://camera_rig.gd" id="3_h2yge"]
[ext_resource type="PackedScene" uid="uid://be6ufrc3dsjge" path="res://poi.tscn" id="5_lquwl"]
[ext_resource type="PackedScene" uid="uid://dmhs1oy1kh6hi" path="res://assets/models/mountain.glb" id="6_7mycd"]
[ext_resource type="PackedScene" uid="uid://gl4qpk4wto1e" path="res://assets/models/mountain2v5.glb" id="7_272bh"]
[ext_resource type="PackedScene" uid="uid://be2uq7ixlbv6b" path="res://assets/models/forest.glb" id="8_5vw27"]
[sub_resource type="Environment" id="Environment_h2yge"]
ambient_light_color = Color(0, 0, 0.31764707, 1)
ambient_light_energy = 0.3
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_lquwl"]
albedo_texture = ExtResource("1_1bvp3")
[sub_resource type="CylinderMesh" id="CylinderMesh_lquwl"]
top_radius = 100.0
bottom_radius = 100.0
height = 0.2
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_h2yge"]
shading_mode = 0
albedo_color = Color(0, 0.32156864, 0, 1)
[sub_resource type="CylinderShape3D" id="CylinderShape3D_lquwl"]
height = 0.2
radius = 100.0
[sub_resource type="CylinderShape3D" id="CylinderShape3D_7mycd"]
height = 0.5
radius = 0.16
[sub_resource type="AtlasTexture" id="AtlasTexture_lquwl"]
atlas = ExtResource("2_h2yge")
region = Rect2(0, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_7mycd"]
atlas = ExtResource("2_h2yge")
region = Rect2(48, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_272bh"]
atlas = ExtResource("2_h2yge")
region = Rect2(96, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_5vw27"]
atlas = ExtResource("2_h2yge")
region = Rect2(0, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_kek77"]
atlas = ExtResource("2_h2yge")
region = Rect2(48, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_4c57u"]
atlas = ExtResource("2_h2yge")
region = Rect2(96, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_efxa6"]
atlas = ExtResource("2_h2yge")
region = Rect2(0, 60, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_dg77c"]
atlas = ExtResource("2_h2yge")
region = Rect2(48, 60, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_ycdy4"]
atlas = ExtResource("2_h2yge")
region = Rect2(96, 60, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_w48qg"]
atlas = ExtResource("2_h2yge")
region = Rect2(0, 120, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_vivmo"]
atlas = ExtResource("2_h2yge")
region = Rect2(48, 120, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_2cqfq"]
atlas = ExtResource("2_h2yge")
region = Rect2(96, 120, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_yaehf"]
atlas = ExtResource("2_h2yge")
region = Rect2(0, 180, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_074og"]
atlas = ExtResource("2_h2yge")
region = Rect2(48, 180, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_cegan"]
atlas = ExtResource("2_h2yge")
region = Rect2(96, 180, 48, 60)
[sub_resource type="SpriteFrames" id="SpriteFrames_82xsv"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_lquwl")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_7mycd")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_272bh")
}],
"loop": true,
"name": &"idle",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_5vw27")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kek77")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_4c57u")
}],
"loop": true,
"name": &"move_down",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_efxa6")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_dg77c")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ycdy4")
}],
"loop": true,
"name": &"move_left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_w48qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_vivmo")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2cqfq")
}],
"loop": true,
"name": &"move_right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_yaehf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_074og")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_cegan")
}],
"loop": true,
"name": &"move_up",
"speed": 5.0
}]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_7mycd"]
radius = 7.0
height = 20.0
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_5vw27"]
radius = 8.5078125
height = 17.015625
[sub_resource type="CylinderShape3D" id="CylinderShape3D_5vw27"]
height = 2.2817383
radius = 0.72021484
[sub_resource type="CylinderShape3D" id="CylinderShape3D_kek77"]
height = 1.8276367
radius = 0.5517578
[node name="Main" type="Node3D" unique_id=1313637872]
[node name="Environment" type="WorldEnvironment" parent="." unique_id=753803863]
environment = SubResource("Environment_h2yge")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=630943989]
[node name="Ground" type="StaticBody3D" parent="." unique_id=309197966]
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground" unique_id=479475733]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00084638596, -0.2, -0.001806736)
material_override = SubResource("StandardMaterial3D_lquwl")
mesh = SubResource("CylinderMesh_lquwl")
surface_material_override/0 = SubResource("StandardMaterial3D_h2yge")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground" unique_id=1301061872]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.2, 0)
shape = SubResource("CylinderShape3D_lquwl")
[node name="Player" type="CharacterBody3D" parent="." unique_id=1504574304 groups=["player"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0)
script = ExtResource("1_0xm2m")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Player" unique_id=1483851051]
shape = SubResource("CylinderShape3D_7mycd")
[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="Player" unique_id=155581900]
billboard = 2
texture_filter = 0
sprite_frames = SubResource("SpriteFrames_82xsv")
animation = &"idle"
[node name="CameraRig" type="Node3D" parent="." unique_id=1094565525 groups=["camera_rig"]]
script = ExtResource("3_h2yge")
target = NodePath("../Player")
[node name="CameraArm" type="Node3D" parent="CameraRig" unique_id=1827622739]
transform = Transform3D(1, 0, 0, 0, 0.81915206, 0.57357645, 0, -0.57357645, 0.81915206, 0, 0, 0)
[node name="Camera3D" type="Camera3D" parent="CameraRig/CameraArm" unique_id=1414235198]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 12)
fov = 50.0
near = 0.1
far = 500.0
[node name="POI" parent="." unique_id=1770000468 instance=ExtResource("5_lquwl")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 2)
[node name="Node3D" type="Node3D" parent="." unique_id=597556846]
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 3.6214647, -0.23645921, 0.47627413)
[node name="mountain" parent="Node3D" unique_id=2116024014 instance=ExtResource("6_7mycd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -7.0459113)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D/mountain" unique_id=1378662574]
shape = SubResource("CapsuleShape3D_7mycd")
[node name="mountain2" parent="Node3D" unique_id=1164111955 instance=ExtResource("6_7mycd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.6505966, 0, -7.0459113)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D/mountain2" unique_id=1044531282]
shape = SubResource("CapsuleShape3D_7mycd")
[node name="mountain3" parent="Node3D" unique_id=1031030133 instance=ExtResource("6_7mycd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.5228462, 0, -2.3011575)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D/mountain3" unique_id=1670981761]
shape = SubResource("CapsuleShape3D_7mycd")
[node name="mountain4" parent="Node3D" unique_id=213527076 instance=ExtResource("6_7mycd")]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D/mountain4" unique_id=370339188]
shape = SubResource("CapsuleShape3D_7mycd")
[node name="Node3D2" type="Node3D" parent="." unique_id=97687536]
[node name="mountain2v5" parent="Node3D2" unique_id=1347056585 instance=ExtResource("7_272bh")]
transform = Transform3D(0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05, 5.449942, -0.15, 0.60275173)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D2/mountain2v5" unique_id=1250318876]
shape = SubResource("CapsuleShape3D_5vw27")
[node name="mountain2v6" parent="Node3D2" unique_id=722974757 instance=ExtResource("7_272bh")]
transform = Transform3D(0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05, 5.309197, -0.15, 0.16273117)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D2/mountain2v6" unique_id=232796233]
shape = SubResource("CapsuleShape3D_5vw27")
[node name="mountain2v7" parent="Node3D2" unique_id=279879297 instance=ExtResource("7_272bh")]
transform = Transform3D(0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05, 5.801124, -0.15, -0.25847834)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D2/mountain2v7" unique_id=271099516]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.04194641, 0.13291359, -0.03959179)
shape = SubResource("CapsuleShape3D_5vw27")
[node name="mountain2v8" parent="Node3D2" unique_id=1413121196 instance=ExtResource("7_272bh")]
transform = Transform3D(0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05, 6.2565756, -0.15, 0.1419242)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D2/mountain2v8" unique_id=632282427]
shape = SubResource("CapsuleShape3D_5vw27")
[node name="mountain2v9" parent="Node3D2" unique_id=888354952 instance=ExtResource("7_272bh")]
transform = Transform3D(0.05, 0, 0, 0, 0.05, 0, 0, 0, 0.05, 5.309197, -0.15, -0.051428914)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D2/mountain2v9" unique_id=1549534653]
shape = SubResource("CapsuleShape3D_5vw27")
[node name="Node3D3" type="Node3D" parent="." unique_id=2010190045]
transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 6.5570726, 0.80977285, 4.959112)
[node name="forest" parent="Node3D3" unique_id=1142695276 instance=ExtResource("8_5vw27")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.89663315, -3.8352594, -0.41697693)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D3/forest" unique_id=1992100035]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0569582, -0.37715888, -0.2822442)
shape = SubResource("CylinderShape3D_5vw27")
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Node3D3/forest" unique_id=2004443612]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1139164, -0.75431776, 0.11189556)
shape = SubResource("CylinderShape3D_5vw27")
[node name="CollisionShape3D3" type="CollisionShape3D" parent="Node3D3/forest" unique_id=1398520795]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.4591012, -0.5861306, 0.51387644)
shape = SubResource("CylinderShape3D_5vw27")
[node name="forest2" parent="Node3D3" unique_id=2120638756 instance=ExtResource("8_5vw27")]
transform = Transform3D(-0.87206924, 0, 0.4893825, 0, 1, 0, -0.4893825, 0, -0.87206924, 0, -3.83526, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D3/forest2" unique_id=92773776]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.15763283, -0.2685547, -0.28089857)
shape = SubResource("CylinderShape3D_kek77")
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Node3D3/forest2" unique_id=291722829]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.021739006, -0.5371094, 0.2103684)
shape = SubResource("CylinderShape3D_kek77")
[node name="CollisionShape3D3" type="CollisionShape3D" parent="Node3D3/forest2" unique_id=1876581014]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.084690094, -0.5371094, 0.40002155)
shape = SubResource("CylinderShape3D_kek77")

8
modeltest.tscn Normal file
View File

@ -0,0 +1,8 @@
[gd_scene format=3 uid="uid://b645207svctxk"]
[ext_resource type="PackedScene" uid="uid://dmhs1oy1kh6hi" path="res://assets/models/mountain.glb" id="1_lqtyj"]
[node name="TestModelworld" type="Node3D" unique_id=2084483331]
[node name="mountain" parent="." unique_id=2029213902 instance=ExtResource("1_lqtyj")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.034547806, 1.1920929e-07, -0.028554201)

62
player.gd Executable file
View File

@ -0,0 +1,62 @@
extends CharacterBody3D
@export var move_speed: float = 5.0
@export var gravity: float = 9.8
var camera_rig: Node3D
@onready var sprite: AnimatedSprite3D = $AnimatedSprite3D
func _ready() -> void:
camera_rig = get_tree().get_first_node_in_group("camera_rig")
if camera_rig == null:
push_error("CameraRig nicht gefunden! Gruppe 'camera_rig' gesetzt?")
func _physics_process(delta: float) -> void:
# Bewegung sperren während Interaction
if InteractionManager.active:
velocity = Vector3.ZERO
return
# Schwerkraft
if not is_on_floor():
velocity.y -= gravity * delta
# Eingabe
var input_dir = Vector2(
Input.get_axis("move_left", "move_right"),
Input.get_axis("move_forward", "move_backward")
)
if input_dir != Vector2.ZERO:
var cam_basis = camera_rig.global_transform.basis
var forward = -cam_basis.z
var right = cam_basis.x
forward.y = 0
right.y = 0
forward = forward.normalized()
right = right.normalized()
var move_dir = (forward * -input_dir.y + right * input_dir.x).normalized()
velocity.x = move_dir.x * move_speed
velocity.z = move_dir.z * move_speed
_update_animation(input_dir)
else:
velocity.x = move_toward(velocity.x, 0, move_speed)
velocity.z = move_toward(velocity.z, 0, move_speed)
sprite.play("idle")
move_and_slide()
func _update_animation(input_dir: Vector2) -> void:
if input_dir.y > 0.1:
sprite.play("move_down")
elif input_dir.y < -0.1:
sprite.play("move_up")
elif input_dir.x > 0.1:
sprite.play("move_right")
elif input_dir.x < -0.1:
sprite.play("move_left")
else:
sprite.play("idle")

1
player.gd.uid Executable file
View File

@ -0,0 +1 @@
uid://ckrqvbqw08kin

153
player.tscn Normal file
View File

@ -0,0 +1,153 @@
[gd_scene format=3 uid="uid://dljjlqptwc2a2"]
[ext_resource type="Script" uid="uid://ckrqvbqw08kin" path="res://player.gd" id="1_onrkg"]
[ext_resource type="Texture2D" uid="uid://epcqli428yem" path="res://assets/sprites/player/debug_player.png" id="2_i3pqv"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_7mycd"]
height = 0.5
radius = 0.16
[sub_resource type="AtlasTexture" id="AtlasTexture_lquwl"]
atlas = ExtResource("2_i3pqv")
region = Rect2(0, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_7mycd"]
atlas = ExtResource("2_i3pqv")
region = Rect2(48, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_272bh"]
atlas = ExtResource("2_i3pqv")
region = Rect2(96, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_5vw27"]
atlas = ExtResource("2_i3pqv")
region = Rect2(0, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_kek77"]
atlas = ExtResource("2_i3pqv")
region = Rect2(48, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_4c57u"]
atlas = ExtResource("2_i3pqv")
region = Rect2(96, 0, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_efxa6"]
atlas = ExtResource("2_i3pqv")
region = Rect2(0, 60, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_dg77c"]
atlas = ExtResource("2_i3pqv")
region = Rect2(48, 60, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_ycdy4"]
atlas = ExtResource("2_i3pqv")
region = Rect2(96, 60, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_w48qg"]
atlas = ExtResource("2_i3pqv")
region = Rect2(0, 120, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_vivmo"]
atlas = ExtResource("2_i3pqv")
region = Rect2(48, 120, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_2cqfq"]
atlas = ExtResource("2_i3pqv")
region = Rect2(96, 120, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_yaehf"]
atlas = ExtResource("2_i3pqv")
region = Rect2(0, 180, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_074og"]
atlas = ExtResource("2_i3pqv")
region = Rect2(48, 180, 48, 60)
[sub_resource type="AtlasTexture" id="AtlasTexture_cegan"]
atlas = ExtResource("2_i3pqv")
region = Rect2(96, 180, 48, 60)
[sub_resource type="SpriteFrames" id="SpriteFrames_82xsv"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_lquwl")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_7mycd")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_272bh")
}],
"loop": true,
"name": &"idle",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_5vw27")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_kek77")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_4c57u")
}],
"loop": true,
"name": &"move_down",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_efxa6")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_dg77c")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ycdy4")
}],
"loop": true,
"name": &"move_left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_w48qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_vivmo")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_2cqfq")
}],
"loop": true,
"name": &"move_right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_yaehf")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_074og")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_cegan")
}],
"loop": true,
"name": &"move_up",
"speed": 5.0
}]
[node name="Player" type="CharacterBody3D" unique_id=1949521754 groups=["player"]]
script = ExtResource("1_onrkg")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=2092151561]
shape = SubResource("CylinderShape3D_7mycd")
[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="." unique_id=1093854571]
billboard = 2
texture_filter = 0
sprite_frames = SubResource("SpriteFrames_82xsv")
animation = &"idle"

48
poi.gd Executable file
View File

@ -0,0 +1,48 @@
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)

1
poi.gd.uid Executable file
View File

@ -0,0 +1 @@
uid://c12tpdqhr2l5

55
poi.tscn Executable file
View File

@ -0,0 +1,55 @@
[gd_scene format=3 uid="uid://be6ufrc3dsjge"]
[ext_resource type="Script" uid="uid://c12tpdqhr2l5" path="res://poi.gd" id="1_gwpk6"]
[ext_resource type="Texture2D" uid="uid://c0u8xjymrfw2x" path="res://assets/sprites/enviroment/Brown-gray_ruins2.png" id="2_yof6k"]
[sub_resource type="SphereShape3D" id="SphereShape3D_gwpk6"]
radius = 0.8699188
[sub_resource type="AtlasTexture" id="AtlasTexture_mekjb"]
atlas = ExtResource("2_yof6k")
region = Rect2(0, 0, 80, 80)
[sub_resource type="SpriteFrames" id="SpriteFrames_0surh"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_mekjb")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[sub_resource type="BoxShape3D" id="BoxShape3D_gwpk6"]
size = Vector3(0.8, 2.132, 2.333828)
[node name="POI" type="Area3D" unique_id=1770000468]
script = ExtResource("1_gwpk6")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=2115487742]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.6096671)
shape = SubResource("SphereShape3D_gwpk6")
[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="." unique_id=1205831120]
sprite_frames = SubResource("SpriteFrames_0surh")
[node name="StaticBody3D" type="StaticBody3D" parent="." unique_id=1488376384]
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" unique_id=461988177]
transform = Transform3D(0.6, 0, 0, 0, 0.6, 0, 0, 0, 0.6, 0, 0, -0.69380605)
shape = SubResource("BoxShape3D_gwpk6")
[node name="Billboard" type="Node3D" parent="." unique_id=36237536]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
[node name="NameLabel" type="Label3D" parent="Billboard" unique_id=1419647885]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
billboard = 1
text = "???"
font_size = 16
[node name="InteractionPrompt" type="Label3D" parent="Billboard" unique_id=2059219662]
visible = false
billboard = 1
font_size = 12

View File

@ -0,0 +1,16 @@
[gd_scene format=3 uid="uid://e8b1otd57xce"]
[ext_resource type="Script" uid="uid://dehw4udbgwx4f" path="res://hightmap_gen.gd" id="1_regv8"]
[ext_resource type="Script" uid="uid://db1kymxglg8m1" path="res://preview_camera.gd" id="2_ji7iu"]
[node name="PreviewScene" type="Node2D" unique_id=887284748]
[node name="HightmapGen" type="Node" parent="." unique_id=1525090931]
script = ExtResource("1_regv8")
[node name="preview_camera" type="Camera2D" parent="." unique_id=1468922324]
script = ExtResource("2_ji7iu")
[node name="TextureRect" type="TextureRect" parent="." unique_id=1360046958]
offset_right = 40.0
offset_bottom = 40.0

View File

@ -0,0 +1,16 @@
[gd_scene format=3 uid="uid://e8b1otd57xce"]
[ext_resource type="Script" uid="uid://dehw4udbgwx4f" path="res://hightmap_gen.gd" id="1_regv8"]
[ext_resource type="Script" uid="uid://db1kymxglg8m1" path="res://preview_camera.gd" id="2_ji7iu"]
[node name="PreviewScene" type="Node2D" unique_id=887284748]
[node name="HightmapGen" type="Node" parent="." unique_id=1525090931]
script = ExtResource("1_regv8")
[node name="preview_camera" type="Camera2D" parent="." unique_id=1468922324]
script = ExtResource("2_ji7iu")
[node name="TextureRect" type="TextureRect" parent="." unique_id=1360046958]
offset_right = 40.0
offset_bottom = 40.0

128
project.godot Executable file
View File

@ -0,0 +1,128 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="WayfarersWanderer"
run/main_scene="uid://bju1lndv8l1mo"
config/features=PackedStringArray("4.6", "GL Compatibility")
[autoload]
InteractionManager="*uid://cbg1abspfwgxo"
InteractionUI="*uid://cmg2008xfel2v"
[display]
window/size/viewport_width=1280
window/size/viewport_height=720
[editor_plugins]
enabled=PackedStringArray("res://addons/zylann.hterrain/plugin.cfg")
[input]
move_forward={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
]
}
move_backward={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
]
}
move_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
]
}
move_right={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
]
}
cam_rotate_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":false,"script":null)
]
}
cam_rotate_right={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":false,"script":null)
]
}
zoom_in={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194437,"key_label":0,"unicode":43,"location":0,"echo":false,"script":null)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
]
}
zoom_out={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194435,"key_label":0,"unicode":45,"location":0,"echo":false,"script":null)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
]
}
interact={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
cancel={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_select_up={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_select_down={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_select_left={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
]
}
ui_select_right={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
]
}
[physics]
3d/physics_engine="Jolt Physics"
[rendering]
rendering_device/driver.windows="d3d12"
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"