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:
commit
fa38e603a1
4
.editorconfig
Executable file
4
.editorconfig
Executable file
@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
2
.gitattributes
vendored
Executable file
2
.gitattributes
vendored
Executable file
@ -0,0 +1,2 @@
|
||||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
||||
3
.gitignore
vendored
Executable file
3
.gitignore
vendored
Executable file
@ -0,0 +1,3 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
/android/
|
||||
BIN
assets/debug/checkerboard.png
Executable file
BIN
assets/debug/checkerboard.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 602 B |
41
assets/debug/checkerboard.png.import
Executable file
41
assets/debug/checkerboard.png.import
Executable 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
BIN
assets/models/forest.glb
Normal file
Binary file not shown.
42
assets/models/forest.glb.import
Normal file
42
assets/models/forest.glb.import
Normal 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
|
||||
BIN
assets/models/forest_tree_greenv1.png
Normal file
BIN
assets/models/forest_tree_greenv1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
44
assets/models/forest_tree_greenv1.png.import
Normal file
44
assets/models/forest_tree_greenv1.png.import
Normal 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
BIN
assets/models/mountain.glb
Normal file
Binary file not shown.
42
assets/models/mountain.glb.import
Normal file
42
assets/models/mountain.glb.import
Normal 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
|
||||
BIN
assets/models/mountain2v5.glb
Normal file
BIN
assets/models/mountain2v5.glb
Normal file
Binary file not shown.
42
assets/models/mountain2v5.glb.import
Normal file
42
assets/models/mountain2v5.glb.import
Normal 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
|
||||
BIN
assets/sprites/enviroment/Brown-gray_ruins2.png
Executable file
BIN
assets/sprites/enviroment/Brown-gray_ruins2.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
41
assets/sprites/enviroment/Brown-gray_ruins2.png.import
Executable file
41
assets/sprites/enviroment/Brown-gray_ruins2.png.import
Executable 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
|
||||
BIN
assets/sprites/player/debug_player.png
Executable file
BIN
assets/sprites/player/debug_player.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
41
assets/sprites/player/debug_player.png.import
Executable file
41
assets/sprites/player/debug_player.png.import
Executable 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
77
camera_rig.gd
Executable 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
1
camera_rig.gd.uid
Executable file
@ -0,0 +1 @@
|
||||
uid://b0y06y7c0bihj
|
||||
34
debug/FreeCam.gd
Normal file
34
debug/FreeCam.gd
Normal 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
1
debug/FreeCam.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://bia8axed2ndwj
|
||||
271
debug/Grenze.gd
Normal file
271
debug/Grenze.gd
Normal 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
1
debug/Grenze.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://cql864jt4i24
|
||||
100
debug/IslandMesh.gd
Normal file
100
debug/IslandMesh.gd
Normal 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
1
debug/IslandMesh.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://d0xuftjl5xssi
|
||||
22
debug/fluss_proto.tscn
Normal file
22
debug/fluss_proto.tscn
Normal 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
36
debug/flying_island.tscn
Normal 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
134
debug/voxel.gd
Normal 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
1
debug/voxel.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://syb1gkanuju7
|
||||
59
interaction_manager.gd
Executable file
59
interaction_manager.gd
Executable 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
1
interaction_manager.gd.uid
Executable file
@ -0,0 +1 @@
|
||||
uid://cbg1abspfwgxo
|
||||
68
interaction_ui.gd
Executable file
68
interaction_ui.gd
Executable 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
1
interaction_ui.gd.uid
Executable file
@ -0,0 +1 @@
|
||||
uid://dv2w4x8t53ym
|
||||
57
interaction_ui.tscn
Executable file
57
interaction_ui.tscn
Executable 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
323
main.tscn
Executable 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
8
modeltest.tscn
Normal 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
62
player.gd
Executable 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
1
player.gd.uid
Executable file
@ -0,0 +1 @@
|
||||
uid://ckrqvbqw08kin
|
||||
153
player.tscn
Normal file
153
player.tscn
Normal 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
48
poi.gd
Executable 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
1
poi.gd.uid
Executable file
@ -0,0 +1 @@
|
||||
uid://c12tpdqhr2l5
|
||||
55
poi.tscn
Executable file
55
poi.tscn
Executable 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
|
||||
16
preview_scene.tscn3183368435.tmp
Executable file
16
preview_scene.tscn3183368435.tmp
Executable 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
|
||||
16
preview_scene.tscn3781868854.tmp
Executable file
16
preview_scene.tscn3781868854.tmp
Executable 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
128
project.godot
Executable 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"
|
||||
Loading…
x
Reference in New Issue
Block a user