Added terrain and robot prototypes
This commit is contained in:
70
nodes/camera/controllable_camera.gd
Normal file
70
nodes/camera/controllable_camera.gd
Normal file
@@ -0,0 +1,70 @@
|
||||
extends Camera3D
|
||||
|
||||
@export var base_move_speed := 5.0
|
||||
@export var min_move_speed := 1.0
|
||||
@export var max_move_speed := 20.0
|
||||
@export var rotation_speed := 0.002
|
||||
|
||||
var input_delay_over := false
|
||||
var current_move_speed := base_move_speed
|
||||
var mouse_delta := Vector2.ZERO
|
||||
var mouse_pos := Vector2.ZERO
|
||||
|
||||
func _process(delta):
|
||||
if Input.is_action_just_pressed("camera_control"):
|
||||
mouse_pos = get_viewport().get_mouse_position()
|
||||
input_delay_over = false
|
||||
get_tree().create_timer(0.15).timeout.connect(
|
||||
func():
|
||||
if Input.is_action_pressed("camera_control"):
|
||||
input_delay_over = true
|
||||
)
|
||||
if Input.is_action_pressed("camera_control") and input_delay_over:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||
handle_movement(delta)
|
||||
handle_rotation()
|
||||
else:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
if Input.is_action_just_released("camera_control") and input_delay_over:
|
||||
Input.warp_mouse(mouse_pos)
|
||||
|
||||
func _unhandled_input(event):
|
||||
if event is InputEventMouseButton and event.is_pressed():
|
||||
handle_scroll_wheel(event)
|
||||
if event is InputEventMouseMotion:
|
||||
mouse_delta = event.relative
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
var input_dir = Vector3.ZERO
|
||||
if Input.is_key_pressed(KEY_W):
|
||||
input_dir.z -= 1
|
||||
if Input.is_key_pressed(KEY_S):
|
||||
input_dir.z += 1
|
||||
if Input.is_key_pressed(KEY_A):
|
||||
input_dir.x -= 1
|
||||
if Input.is_key_pressed(KEY_D):
|
||||
input_dir.x += 1
|
||||
if Input.is_key_pressed(KEY_E):
|
||||
input_dir.y += 1
|
||||
if Input.is_key_pressed(KEY_Q):
|
||||
input_dir.y -= 1
|
||||
|
||||
if input_dir.length() > 0:
|
||||
input_dir = input_dir.normalized()
|
||||
translate(input_dir * current_move_speed * delta)
|
||||
|
||||
func handle_rotation() -> void:
|
||||
var current_rotation_x = rotation.x - mouse_delta.y * rotation_speed
|
||||
current_rotation_x = clamp(current_rotation_x, -1.5, 1.5)
|
||||
var current_rotation_y = rotation.y - mouse_delta.x * rotation_speed
|
||||
rotation = Vector3(current_rotation_x, current_rotation_y, 0)
|
||||
mouse_delta = Vector2.ZERO
|
||||
|
||||
func handle_scroll_wheel(event: InputEventMouseButton ) -> void:
|
||||
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||||
adjust_move_speed(1.0)
|
||||
elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||||
adjust_move_speed(-1.0)
|
||||
|
||||
func adjust_move_speed(delta: float) -> void:
|
||||
current_move_speed = clamp(current_move_speed + delta, min_move_speed, max_move_speed)
|
||||
1
nodes/camera/controllable_camera.gd.uid
Normal file
1
nodes/camera/controllable_camera.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://le0spo0q018k
|
||||
9
nodes/camera/controllable_camera.tscn
Normal file
9
nodes/camera/controllable_camera.tscn
Normal file
@@ -0,0 +1,9 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://cy0nvmw51bwof"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://le0spo0q018k" path="res://nodes/camera/controllable_camera.gd" id="1_fgom1"]
|
||||
|
||||
[node name="ControllableCamera" type="Camera3D"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
script = ExtResource("1_fgom1")
|
||||
|
||||
[node name="VoxelViewer" type="VoxelViewer" parent="."]
|
||||
54
nodes/coding/code_runner.gd
Normal file
54
nodes/coding/code_runner.gd
Normal file
@@ -0,0 +1,54 @@
|
||||
extends Node
|
||||
|
||||
@onready var code_editor := $%Code as CodeEdit
|
||||
@onready var memory := $%Memory as VBoxContainer
|
||||
@onready var memory_entry := load("uid://dqwi5rekytyds") as PackedScene
|
||||
var cobor_vm := CoborVirtualMachine.new()
|
||||
|
||||
func _ready() -> void:
|
||||
cobor_vm.set_registers(8,[])
|
||||
for i in range(8):
|
||||
var entry := memory_entry.instantiate() as Control
|
||||
(entry.get_node("address") as Label).text = "/" + str(i) + " = "
|
||||
(entry.get_node("value") as SpinBox).value = 0
|
||||
memory.add_child(entry)
|
||||
|
||||
func _tick() -> void:
|
||||
if code_editor.editable: return
|
||||
for line in code_editor.get_executing_lines():
|
||||
code_editor.set_line_as_executing(line, false)
|
||||
code_editor.set_line_as_executing(cobor_vm.get_program_counter(), true)
|
||||
var err := cobor_vm.run_step()
|
||||
if not err.is_empty():
|
||||
print(err);
|
||||
var registers := cobor_vm.get_registers()
|
||||
for i in range(8):
|
||||
var entry := memory.get_child(i) as Control
|
||||
(entry.get_node("value") as SpinBox).value = registers[i]
|
||||
|
||||
func _on_compile_button_pressed() -> void:
|
||||
var text := code_editor.text
|
||||
var errors := cobor_vm.parse_source_code(text)
|
||||
if errors.is_empty():
|
||||
print("Compiling Ok!")
|
||||
else:
|
||||
for error in errors:
|
||||
print(error)
|
||||
|
||||
func _on_stop_button_pressed() -> void:
|
||||
code_editor.editable = true
|
||||
$Timer.stop()
|
||||
cobor_vm.set_registers(8,[])
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
code_editor.editable = false
|
||||
_on_compile_button_pressed();
|
||||
$Timer.start()
|
||||
|
||||
func _on_pause_button_pressed() -> void:
|
||||
$Timer.stop()
|
||||
|
||||
|
||||
func _on_step_button_pressed() -> void:
|
||||
code_editor.editable = false
|
||||
_tick()
|
||||
1
nodes/coding/code_runner.gd.uid
Normal file
1
nodes/coding/code_runner.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://brnfd6h7eh0n7
|
||||
87
nodes/coding/code_runner.tscn
Normal file
87
nodes/coding/code_runner.tscn
Normal file
@@ -0,0 +1,87 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://7q00x01xdsal"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://brnfd6h7eh0n7" path="res://nodes/coding/code_runner.gd" id="1_mphwn"]
|
||||
|
||||
[node name="CodeRunner" type="Node"]
|
||||
script = ExtResource("1_mphwn")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
|
||||
[node name="ProgrammerUI" type="PanelContainer" parent="."]
|
||||
anchors_preset = 9
|
||||
anchor_bottom = 1.0
|
||||
offset_right = 314.0
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ProgrammerUI"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="Label" type="Label" parent="ProgrammerUI/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Programming"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="ProgrammerUI/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="ProgrammerUI/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="ProgrammerUI/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = " Source Code "
|
||||
|
||||
[node name="Code" type="CodeEdit" parent="ProgrammerUI/VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(200, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
text = "Set 1 /2
|
||||
Cpy /2 /3
|
||||
Add /2 /3 /3
|
||||
|
||||
"
|
||||
placeholder_text = "Code here"
|
||||
symbol_tooltip_on_hover = true
|
||||
line_length_guidelines = Array[int]([5, 7, 9, 11])
|
||||
gutters_draw_executing_lines = true
|
||||
gutters_draw_line_numbers = true
|
||||
gutters_zero_pad_line_numbers = true
|
||||
|
||||
[node name="Memory" type="VBoxContainer" parent="ProgrammerUI/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="ProgrammerUI/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
alignment = 1
|
||||
|
||||
[node name="compileButton" type="Button" parent="ProgrammerUI/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = "[C]"
|
||||
|
||||
[node name="StopButton" type="Button" parent="ProgrammerUI/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = "[ ]"
|
||||
|
||||
[node name="PlayButton" type="Button" parent="ProgrammerUI/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = ">"
|
||||
|
||||
[node name="PauseButton" type="Button" parent="ProgrammerUI/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = "||"
|
||||
|
||||
[node name="StepButton" type="Button" parent="ProgrammerUI/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = ">|"
|
||||
|
||||
[connection signal="timeout" from="Timer" to="." method="_tick"]
|
||||
[connection signal="pressed" from="ProgrammerUI/VBoxContainer/HBoxContainer2/compileButton" to="." method="_on_compile_button_pressed"]
|
||||
[connection signal="pressed" from="ProgrammerUI/VBoxContainer/HBoxContainer2/StopButton" to="." method="_on_stop_button_pressed"]
|
||||
[connection signal="pressed" from="ProgrammerUI/VBoxContainer/HBoxContainer2/PlayButton" to="." method="_on_play_button_pressed"]
|
||||
[connection signal="pressed" from="ProgrammerUI/VBoxContainer/HBoxContainer2/PauseButton" to="." method="_on_pause_button_pressed"]
|
||||
[connection signal="pressed" from="ProgrammerUI/VBoxContainer/HBoxContainer2/StepButton" to="." method="_on_step_button_pressed"]
|
||||
16
nodes/coding/memory_entry.tscn
Normal file
16
nodes/coding/memory_entry.tscn
Normal file
@@ -0,0 +1,16 @@
|
||||
[gd_scene format=3 uid="uid://dqwi5rekytyds"]
|
||||
|
||||
[node name="memory_entry" type="HBoxContainer"]
|
||||
|
||||
[node name="address" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
text = "/0 = "
|
||||
|
||||
[node name="value" type="SpinBox" parent="."]
|
||||
layout_mode = 2
|
||||
value = 4.0
|
||||
rounded = true
|
||||
allow_greater = true
|
||||
allow_lesser = true
|
||||
alignment = 1
|
||||
editable = false
|
||||
3
nodes/game.tscn
Normal file
3
nodes/game.tscn
Normal file
@@ -0,0 +1,3 @@
|
||||
[gd_scene format=3 uid="uid://d0b7m4vykcfy2"]
|
||||
|
||||
[node name="Game" type="Node"]
|
||||
109
nodes/robots/Robots.tscn
Normal file
109
nodes/robots/Robots.tscn
Normal file
@@ -0,0 +1,109 @@
|
||||
[gd_scene load_steps=18 format=3 uid="uid://b84ihb5xw37pm"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cy0nvmw51bwof" path="res://nodes/camera/controllable_camera.tscn" id="1_ecqtg"]
|
||||
[ext_resource type="Script" uid="uid://bnw0h8cuyf3g5" path="res://nodes/robots/robot.gd" id="1_nnl6p"]
|
||||
[ext_resource type="VoxelBlockyLibrary" uid="uid://bsue4rd3wdfsl" path="res://nodes/word/BlockLibrary.tres" id="1_r886l"]
|
||||
[ext_resource type="Material" uid="uid://de6s8en5fcyyw" path="res://nodes/word/BlockMaterial.tres" id="2_nnl6p"]
|
||||
[ext_resource type="PackedScene" uid="uid://ddyulj4dsrkms" path="res://nodes/word/terrain_editor.tscn" id="4_llm6e"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_e1sxe"]
|
||||
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||
ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||
|
||||
[sub_resource type="Sky" id="Sky_0wfyh"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_e1sxe")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_5yot8"]
|
||||
background_mode = 2
|
||||
sky = SubResource("Sky_0wfyh")
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o5qli"]
|
||||
albedo_color = Color(0.313808, 0.455394, 0.721014, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_oo1c2"]
|
||||
material = SubResource("StandardMaterial3D_o5qli")
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r886l"]
|
||||
albedo_color = Color(0.999686, 0.38438, 0, 1)
|
||||
|
||||
[sub_resource type="PrismMesh" id="PrismMesh_nnl6p"]
|
||||
material = SubResource("StandardMaterial3D_r886l")
|
||||
size = Vector3(0.5, 0.5, 0.25)
|
||||
|
||||
[sub_resource type="TorusMesh" id="TorusMesh_llm6e"]
|
||||
inner_radius = 0.75
|
||||
outer_radius = 0.8
|
||||
rings = 20
|
||||
ring_segments = 6
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jq1ic"]
|
||||
emission_enabled = true
|
||||
emission = Color(0, 1, 1, 1)
|
||||
emission_energy_multiplier = 3.0
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_llm6e"]
|
||||
height = 1.0
|
||||
|
||||
[sub_resource type="VoxelGeneratorFlat" id="VoxelGeneratorFlat_llm6e"]
|
||||
channel = 0
|
||||
|
||||
[sub_resource type="VoxelMesherBlocky" id="VoxelMesherBlocky_ofs8c"]
|
||||
library = ExtResource("1_r886l")
|
||||
|
||||
[node name="Robots" type="Node"]
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_5yot8")
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0)
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="Robot" type="CharacterBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.5, 0.5)
|
||||
script = ExtResource("1_nnl6p")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Robot"]
|
||||
mesh = SubResource("BoxMesh_oo1c2")
|
||||
|
||||
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Robot"]
|
||||
transform = Transform3D(-1, 1.50996e-07, -6.60024e-15, 0, -4.37114e-08, -1, -1.50996e-07, -1, 4.37114e-08, 0, 0.50484, -0.3)
|
||||
mesh = SubResource("PrismMesh_nnl6p")
|
||||
|
||||
[node name="indicator" type="Node3D" parent="Robot"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, 0)
|
||||
visible = false
|
||||
|
||||
[node name="MeshInstance3D3" type="MeshInstance3D" parent="Robot/indicator"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||
mesh = SubResource("TorusMesh_llm6e")
|
||||
skeleton = NodePath("../..")
|
||||
surface_material_override/0 = SubResource("StandardMaterial3D_jq1ic")
|
||||
|
||||
[node name="MeshInstance3D4" type="MeshInstance3D" parent="Robot/indicator"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8, 0)
|
||||
mesh = SubResource("TorusMesh_llm6e")
|
||||
skeleton = NodePath("../..")
|
||||
surface_material_override/0 = SubResource("StandardMaterial3D_jq1ic")
|
||||
|
||||
[node name="MeshInstance3D5" type="MeshInstance3D" parent="Robot/indicator"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2, 0)
|
||||
mesh = SubResource("TorusMesh_llm6e")
|
||||
skeleton = NodePath("../..")
|
||||
surface_material_override/0 = SubResource("StandardMaterial3D_jq1ic")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Robot"]
|
||||
shape = SubResource("CapsuleShape3D_llm6e")
|
||||
|
||||
[node name="VoxelTerrain" type="VoxelTerrain" parent="."]
|
||||
generator = SubResource("VoxelGeneratorFlat_llm6e")
|
||||
mesher = SubResource("VoxelMesherBlocky_ofs8c")
|
||||
bounds = AABB(-1040, -32, -1040, 2080, 96, 2080)
|
||||
material_override = ExtResource("2_nnl6p")
|
||||
|
||||
[node name="TerrainEditor" parent="VoxelTerrain" instance=ExtResource("4_llm6e")]
|
||||
|
||||
[node name="ControllableCamera" parent="." instance=ExtResource("1_ecqtg")]
|
||||
transform = Transform3D(0.97668, -0.143377, 0.159808, 0, 0.744336, 0.667805, -0.214699, -0.652232, 0.726979, 1.39679, 4.07542, 4.92893)
|
||||
|
||||
[connection signal="input_event" from="Robot" to="Robot" method="_on_input_event"]
|
||||
56
nodes/robots/robot.gd
Normal file
56
nodes/robots/robot.gd
Normal file
@@ -0,0 +1,56 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
@onready var terrain := get_node("../VoxelTerrain") as VoxelTerrain
|
||||
|
||||
var selected := false
|
||||
var path : Array[Vector3i]
|
||||
|
||||
func _on_input_event(camera: Node, event: InputEvent, event_position: Vector3, normal: Vector3, shape_idx: int) -> void:
|
||||
if event is InputEventMouseButton and event.is_pressed():
|
||||
var button_event = event as InputEventMouseButton
|
||||
if button_event.button_index == MOUSE_BUTTON_LEFT:
|
||||
$indicator.visible = true
|
||||
selected = true
|
||||
elif button_event.button_index == MOUSE_BUTTON_RIGHT:
|
||||
$indicator.visible = false
|
||||
selected = false
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if selected:
|
||||
if event is InputEventMouseButton and event.is_pressed():
|
||||
var button_event = event as InputEventMouseButton
|
||||
if button_event.button_index == MOUSE_BUTTON_LEFT:
|
||||
move_to_mouse_click()
|
||||
elif button_event.button_index == MOUSE_BUTTON_RIGHT:
|
||||
pass
|
||||
|
||||
func move_to_mouse_click():
|
||||
var mouse_pos_2d := get_viewport().get_mouse_position()
|
||||
var current_camera := get_viewport().get_camera_3d()
|
||||
var origin := current_camera.project_ray_origin(mouse_pos_2d)
|
||||
var dir := current_camera.project_ray_normal(mouse_pos_2d)
|
||||
var res := terrain.get_voxel_tool().raycast(origin, dir, 100)
|
||||
var path_finder := VoxelAStarGrid3D.new()
|
||||
path_finder.set_terrain(terrain)
|
||||
path_finder.set_region(AABB(Vector3.ONE * -100, Vector3.ONE * 200))
|
||||
path = path_finder.find_path(Vector3i(global_position), res.previous_position)
|
||||
path.append(res.previous_position)
|
||||
for step in path:
|
||||
print(step)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not path.is_empty():
|
||||
var next_position := Vector3(path[0]) + Vector3.ONE * 0.5;
|
||||
if path.size() == 1:
|
||||
if next_position.distance_to(global_position) < 0.1:
|
||||
rotation.x = 0
|
||||
rotation.y = round(rotation.y/(PI/2))*PI/2
|
||||
rotation.z = 0
|
||||
print("arrived")
|
||||
if next_position.distance_to(global_position) < 0.1:
|
||||
global_position = next_position
|
||||
path.remove_at(0)
|
||||
else:
|
||||
look_at(next_position)
|
||||
velocity = (next_position - global_position).normalized() * 5
|
||||
move_and_slide()
|
||||
1
nodes/robots/robot.gd.uid
Normal file
1
nodes/robots/robot.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bnw0h8cuyf3g5
|
||||
16
nodes/word/BlockLibrary.tres
Normal file
16
nodes/word/BlockLibrary.tres
Normal file
@@ -0,0 +1,16 @@
|
||||
[gd_resource type="VoxelBlockyLibrary" load_steps=4 format=3 uid="uid://bsue4rd3wdfsl"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://de6s8en5fcyyw" path="res://nodes/word/BlockMaterial.tres" id="1_evy8o"]
|
||||
|
||||
[sub_resource type="VoxelBlockyModelEmpty" id="VoxelBlockyModelEmpty_o5qli"]
|
||||
|
||||
[sub_resource type="VoxelBlockyModelCube" id="VoxelBlockyModelCube_0wfyh"]
|
||||
material_override_0 = ExtResource("1_evy8o")
|
||||
tile_left = Vector2i(0, 1)
|
||||
tile_right = Vector2i(0, 1)
|
||||
tile_bottom = Vector2i(1, 0)
|
||||
tile_back = Vector2i(0, 1)
|
||||
tile_front = Vector2i(0, 1)
|
||||
|
||||
[resource]
|
||||
models = Array[VoxelBlockyModel]([SubResource("VoxelBlockyModelEmpty_o5qli"), SubResource("VoxelBlockyModelCube_0wfyh")])
|
||||
7
nodes/word/BlockMaterial.tres
Normal file
7
nodes/word/BlockMaterial.tres
Normal file
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://de6s8en5fcyyw"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bcctuptks33yd" path="res://nodes/word/blocky_game_atlas.webp" id="1_nmlo6"]
|
||||
|
||||
[resource]
|
||||
albedo_texture = ExtResource("1_nmlo6")
|
||||
texture_filter = 0
|
||||
BIN
nodes/word/blocky_game_atlas.webp
Normal file
BIN
nodes/word/blocky_game_atlas.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
35
nodes/word/blocky_game_atlas.webp.import
Normal file
35
nodes/word/blocky_game_atlas.webp.import
Normal file
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bcctuptks33yd"
|
||||
path.s3tc="res://.godot/imported/blocky_game_atlas.webp-87ad14449ec94b96fe28d0038a51ce08.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://nodes/word/blocky_game_atlas.webp"
|
||||
dest_files=["res://.godot/imported/blocky_game_atlas.webp-87ad14449ec94b96fe28d0038a51ce08.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=2
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=1
|
||||
roughness/src_normal=""
|
||||
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
|
||||
32
nodes/word/terrain_editor.gd
Normal file
32
nodes/word/terrain_editor.gd
Normal file
@@ -0,0 +1,32 @@
|
||||
extends Node
|
||||
|
||||
@onready var voxelTool := (get_parent() as VoxelTerrain).get_voxel_tool()
|
||||
|
||||
var block_edit := false
|
||||
|
||||
func _unhandled_input(event):
|
||||
if event is InputEventMouseButton and event.is_pressed():
|
||||
if block_edit:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||
perform_block_action(true)
|
||||
elif event.button_index == MOUSE_BUTTON_RIGHT:
|
||||
get_tree().create_timer(0.15).timeout.connect(
|
||||
func():
|
||||
if not Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||
perform_block_action(false)
|
||||
)
|
||||
|
||||
func perform_block_action(add_block:bool)->void:
|
||||
var mouse_pos_2d := get_viewport().get_mouse_position()
|
||||
var current_camera := get_viewport().get_camera_3d()
|
||||
var origin := current_camera.project_ray_origin(mouse_pos_2d)
|
||||
var dir := current_camera.project_ray_normal(mouse_pos_2d)
|
||||
var res := voxelTool.raycast(origin, dir, 50)
|
||||
if res != null:
|
||||
if add_block:
|
||||
voxelTool.set_voxel(res.previous_position, 1)
|
||||
else:
|
||||
voxelTool.set_voxel(res.position, 0)
|
||||
|
||||
func _on_button_toggled(toggled_on: bool) -> void:
|
||||
block_edit = toggled_on
|
||||
1
nodes/word/terrain_editor.gd.uid
Normal file
1
nodes/word/terrain_editor.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://vnjdiql72brq
|
||||
22
nodes/word/terrain_editor.tscn
Normal file
22
nodes/word/terrain_editor.tscn
Normal file
@@ -0,0 +1,22 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://ddyulj4dsrkms"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://vnjdiql72brq" path="res://nodes/word/terrain_editor.gd" id="1_6evft"]
|
||||
|
||||
[node name="TerrainEditor" type="Node"]
|
||||
script = ExtResource("1_6evft")
|
||||
|
||||
[node name="Control" type="HBoxContainer" parent="."]
|
||||
anchors_preset = 12
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
alignment = 1
|
||||
|
||||
[node name="Button" type="Button" parent="Control"]
|
||||
layout_mode = 2
|
||||
toggle_mode = true
|
||||
text = "Block Edit"
|
||||
|
||||
[connection signal="toggled" from="Control/Button" to="." method="_on_button_toggled"]
|
||||
49
nodes/word/voxel_world.tscn
Normal file
49
nodes/word/voxel_world.tscn
Normal file
@@ -0,0 +1,49 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://bp6ewa3urgac8"]
|
||||
|
||||
[ext_resource type="VoxelBlockyLibrary" uid="uid://bsue4rd3wdfsl" path="res://nodes/word/BlockLibrary.tres" id="1_yf87h"]
|
||||
[ext_resource type="Material" uid="uid://de6s8en5fcyyw" path="res://nodes/word/BlockMaterial.tres" id="2_j4yt8"]
|
||||
[ext_resource type="PackedScene" uid="uid://cy0nvmw51bwof" path="res://nodes/camera/controllable_camera.tscn" id="3_tcius"]
|
||||
[ext_resource type="PackedScene" uid="uid://ddyulj4dsrkms" path="res://nodes/word/terrain_editor.tscn" id="3_v3kfg"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_gadlc"]
|
||||
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||
ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||
|
||||
[sub_resource type="Sky" id="Sky_t8uwy"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_gadlc")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_5g68j"]
|
||||
background_mode = 2
|
||||
sky = SubResource("Sky_t8uwy")
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_v3kfg"]
|
||||
|
||||
[sub_resource type="VoxelGeneratorNoise2D" id="VoxelGeneratorNoise2D_mko3u"]
|
||||
channel = 0
|
||||
height_start = 0.0
|
||||
height_range = 20.0
|
||||
noise = SubResource("FastNoiseLite_v3kfg")
|
||||
|
||||
[sub_resource type="VoxelMesherBlocky" id="VoxelMesherBlocky_3tbtj"]
|
||||
library = ExtResource("1_yf87h")
|
||||
|
||||
[node name="VoxelWorld" type="Node"]
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_5g68j")
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0, 0, 0)
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="VoxelTerrain" type="VoxelTerrain" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0)
|
||||
generator = SubResource("VoxelGeneratorNoise2D_mko3u")
|
||||
mesher = SubResource("VoxelMesherBlocky_3tbtj")
|
||||
bounds = AABB(-1040, -32, -1040, 2080, 96, 2080)
|
||||
material_override = ExtResource("2_j4yt8")
|
||||
|
||||
[node name="TerrainEditor" parent="VoxelTerrain" instance=ExtResource("3_v3kfg")]
|
||||
|
||||
[node name="ControllableCamera" parent="." instance=ExtResource("3_tcius")]
|
||||
transform = Transform3D(-0.61081, -0.620921, 0.491291, 0, 0.620492, 0.784213, -0.791777, 0.479005, -0.379003, 34.4662, 28.9798, -20.4)
|
||||
Reference in New Issue
Block a user