Compare commits
4 Commits
58b9ce17c8
...
cf0be406ee
Author | SHA1 | Date |
---|---|---|
|
cf0be406ee | |
|
1f561c6f7a | |
|
40cb618efa | |
|
bc2a9f5d87 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,5 +3,5 @@
|
||||||
name="PathMesh3D"
|
name="PathMesh3D"
|
||||||
description="A fast set of 3D mesh extrusion and tiling nodes implemented as a C++ GDExtension."
|
description="A fast set of 3D mesh extrusion and tiling nodes implemented as a C++ GDExtension."
|
||||||
author="iiMidknightii"
|
author="iiMidknightii"
|
||||||
version="1.3.0"
|
version="1.3.1"
|
||||||
script="plugin.gd"
|
script="plugin.gd"
|
||||||
|
|
|
@ -29,24 +29,24 @@ func _exit_tree() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _handles(object: Object) -> bool:
|
func _handles(object: Object) -> bool:
|
||||||
return object is PathMesh3D or object is PathExtrude3D or object is PathScene3D
|
return is_instance_valid(object) and (object is PathMesh3D or object is PathExtrude3D or object is PathScene3D)
|
||||||
|
|
||||||
|
|
||||||
func _edit(object: Object) -> void:
|
func _edit(object: Object) -> void:
|
||||||
if object is PathMesh3D or object is PathExtrude3D and _mesh_editor_button:
|
if is_instance_valid(object) and (object is PathMesh3D or object is PathExtrude3D) and _mesh_editor_button:
|
||||||
_path_object = object
|
_path_object = object
|
||||||
_mesh_editor_button.path_mesh = object
|
_mesh_editor_button.path_mesh = object
|
||||||
_mesh_editor_button.ur = get_undo_redo()
|
_mesh_editor_button.ur = get_undo_redo()
|
||||||
elif object is PathScene3D and _scene_editor_button:
|
elif is_instance_valid(object) and object is PathScene3D and _scene_editor_button:
|
||||||
_path_object = object
|
_path_object = object
|
||||||
_scene_editor_button.path_scene = object
|
_scene_editor_button.path_scene = object
|
||||||
_scene_editor_button.ur = get_undo_redo()
|
_scene_editor_button.ur = get_undo_redo()
|
||||||
|
|
||||||
|
|
||||||
func _make_visible(visible: bool) -> void:
|
func _make_visible(visible: bool) -> void:
|
||||||
if _path_object is PathMesh3D or _path_object is PathExtrude3D and visible:
|
if is_instance_valid(_path_object) and (_path_object is PathMesh3D or _path_object is PathExtrude3D) and visible:
|
||||||
_mesh_editor_button.visible = visible
|
_mesh_editor_button.visible = visible
|
||||||
elif _path_object is PathScene3D and visible:
|
elif is_instance_valid(_path_object) and _path_object is PathScene3D and visible:
|
||||||
_scene_editor_button.visible = visible
|
_scene_editor_button.visible = visible
|
||||||
elif not visible:
|
elif not visible:
|
||||||
_mesh_editor_button.visible = visible
|
_mesh_editor_button.visible = visible
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"column_properties": {
|
||||||
|
"res://items/": {
|
||||||
|
"metadata/_custom_type_script": {
|
||||||
|
"visibility": 0.0
|
||||||
|
},
|
||||||
|
"resource_local_to_scene": {
|
||||||
|
"visibility": 0.0
|
||||||
|
},
|
||||||
|
"resource_name": {
|
||||||
|
"visibility": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"recent_paths": [
|
||||||
|
"res://items/"
|
||||||
|
],
|
||||||
|
"table_functions": {
|
||||||
|
"filter": [
|
||||||
|
"return true"
|
||||||
|
],
|
||||||
|
"process": [
|
||||||
|
"return value"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://cfnfxvcxoapwo"
|
||||||
|
path="res://.godot/imported/Conveyor.blend-ed8c8154849c96ad2284f5e9c12705fd.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/blends/Conveyor.blend"
|
||||||
|
dest_files=["res://.godot/imported/Conveyor.blend-ed8c8154849c96ad2284f5e9c12705fd.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=1.0
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
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=""
|
||||||
|
_subresources={}
|
||||||
|
blender/nodes/visible=0
|
||||||
|
blender/nodes/active_collection_only=false
|
||||||
|
blender/nodes/punctual_lights=true
|
||||||
|
blender/nodes/cameras=true
|
||||||
|
blender/nodes/custom_properties=true
|
||||||
|
blender/nodes/modifiers=1
|
||||||
|
blender/meshes/colors=false
|
||||||
|
blender/meshes/uvs=true
|
||||||
|
blender/meshes/normals=true
|
||||||
|
blender/meshes/export_geometry_nodes_instances=false
|
||||||
|
blender/meshes/tangents=true
|
||||||
|
blender/meshes/skins=2
|
||||||
|
blender/meshes/export_bones_deforming_mesh_only=false
|
||||||
|
blender/materials/unpack_enabled=true
|
||||||
|
blender/materials/export_materials=1
|
||||||
|
blender/animation/limit_playback=true
|
||||||
|
blender/animation/always_sample=true
|
||||||
|
blender/animation/group_tracks=true
|
|
@ -0,0 +1,53 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://bwpnd8l65fn7x"
|
||||||
|
path="res://.godot/imported/Resources.blend-1f000fb8e4330de99f6e9b1d1d341c9f.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/blends/Resources.blend"
|
||||||
|
dest_files=["res://.godot/imported/Resources.blend-1f000fb8e4330de99f6e9b1d1d341c9f.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=1.0
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
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=""
|
||||||
|
_subresources={}
|
||||||
|
blender/nodes/visible=0
|
||||||
|
blender/nodes/active_collection_only=false
|
||||||
|
blender/nodes/punctual_lights=true
|
||||||
|
blender/nodes/cameras=true
|
||||||
|
blender/nodes/custom_properties=true
|
||||||
|
blender/nodes/modifiers=1
|
||||||
|
blender/meshes/colors=false
|
||||||
|
blender/meshes/uvs=true
|
||||||
|
blender/meshes/normals=true
|
||||||
|
blender/meshes/export_geometry_nodes_instances=false
|
||||||
|
blender/meshes/tangents=true
|
||||||
|
blender/meshes/skins=2
|
||||||
|
blender/meshes/export_bones_deforming_mesh_only=false
|
||||||
|
blender/materials/unpack_enabled=true
|
||||||
|
blender/materials/export_materials=1
|
||||||
|
blender/animation/limit_playback=true
|
||||||
|
blender/animation/always_sample=true
|
||||||
|
blender/animation/group_tracks=true
|
Binary file not shown.
After Width: | Height: | Size: 924 B |
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dcny38nrl0kf0"
|
||||||
|
path="res://.godot/imported/splat.png-397849adaf8080e1549558a1d8865428.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/images/splat.png"
|
||||||
|
dest_files=["res://.godot/imported/splat.png-397849adaf8080e1549558a1d8865428.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
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=1
|
|
@ -0,0 +1,25 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wavefront_obj"
|
||||||
|
importer_version=1
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://bv225xw8xssl4"
|
||||||
|
path="res://.godot/imported/Conveyor.obj-7726f330b1d85fa22b1ae73f42a7074b.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
files=["res://.godot/imported/Conveyor.obj-7726f330b1d85fa22b1ae73f42a7074b.mesh"]
|
||||||
|
|
||||||
|
source_file="res://assets/models/Conveyor.obj"
|
||||||
|
dest_files=["res://.godot/imported/Conveyor.obj-7726f330b1d85fa22b1ae73f42a7074b.mesh", "res://.godot/imported/Conveyor.obj-7726f330b1d85fa22b1ae73f42a7074b.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
generate_tangents=true
|
||||||
|
generate_lods=true
|
||||||
|
generate_shadow_mesh=true
|
||||||
|
generate_lightmap_uv2=false
|
||||||
|
generate_lightmap_uv2_texel_size=0.2
|
||||||
|
scale_mesh=Vector3(1, 1, 1)
|
||||||
|
offset_mesh=Vector3(0, 0, 0)
|
||||||
|
force_disable_mesh_compression=false
|
|
@ -0,0 +1,25 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wavefront_obj"
|
||||||
|
importer_version=1
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://c6yj8uwsgqxv0"
|
||||||
|
path="res://.godot/imported/Ingot.obj-a2d5e6fd04e7f87225a4cd53d4193716.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
files=["res://.godot/imported/Ingot.obj-a2d5e6fd04e7f87225a4cd53d4193716.mesh"]
|
||||||
|
|
||||||
|
source_file="res://assets/models/Ingot.obj"
|
||||||
|
dest_files=["res://.godot/imported/Ingot.obj-a2d5e6fd04e7f87225a4cd53d4193716.mesh", "res://.godot/imported/Ingot.obj-a2d5e6fd04e7f87225a4cd53d4193716.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
generate_tangents=true
|
||||||
|
generate_lods=true
|
||||||
|
generate_shadow_mesh=true
|
||||||
|
generate_lightmap_uv2=false
|
||||||
|
generate_lightmap_uv2_texel_size=0.2
|
||||||
|
scale_mesh=Vector3(1, 1, 1)
|
||||||
|
offset_mesh=Vector3(0, 0, 0)
|
||||||
|
force_disable_mesh_compression=false
|
|
@ -1 +1,24 @@
|
||||||
extends GridMap
|
extends GridMap
|
||||||
|
|
||||||
|
var postprocess_done: bool = false
|
||||||
|
|
||||||
|
var postprocess_delay: float = 5.0
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if postprocess_delay > 0:
|
||||||
|
postprocess_delay -= delta
|
||||||
|
if postprocess_delay <= 0 and !postprocess_done:
|
||||||
|
if !NavigationServer3D.get_maps().is_empty():
|
||||||
|
postprocess_done = true
|
||||||
|
var regions_deleted: int = 0
|
||||||
|
var map_rid: RID = NavigationServer3D.get_maps()[0]
|
||||||
|
for cell in get_used_cells():
|
||||||
|
var nav_region_rid: RID = NavigationServer3D.map_get_closest_point_owner(map_rid, to_global(map_to_local(cell)))
|
||||||
|
var upstairs_neighbour: Vector3 = cell + Vector3i(0,1,0)
|
||||||
|
if get_cell_item(upstairs_neighbour) != INVALID_CELL_ITEM:
|
||||||
|
DebugDraw3D.draw_box(to_global(map_to_local(cell)), Quaternion(), Vector3(2,1,2), Color.RED, true, 50)
|
||||||
|
NavigationServer3D.region_set_enabled(nav_region_rid, false)
|
||||||
|
regions_deleted += 1
|
||||||
|
NavigationServer3D.map_force_update(map_rid)
|
||||||
|
print("Navmesh postprocess done; %d regions deleted." % regions_deleted)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
[gd_resource type="Resource" script_class="Item" load_steps=3 format=3 uid="uid://dbkxys3mr5u80"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://kcdpck5ufgcc" path="res://scripts/item.gd" id="1_a88ho"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://xpm6i82tui2o" path="res://assets/images/watchtower.png" id="1_jdpiu"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_a88ho")
|
||||||
|
icon = ExtResource("1_jdpiu")
|
||||||
|
name = "Metal"
|
||||||
|
metadata/_custom_type_script = "uid://kcdpck5ufgcc"
|
82
node_3d.tscn
82
node_3d.tscn
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,28 @@
|
||||||
|
[gd_scene load_steps=4 format=3 uid="uid://b1fnsl3k1mo5c"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dvgo3kpjr2mmj" path="res://scripts/building_components/building.gd" id="1_k07no"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxMesh" id="BoxMesh_cee1v"]
|
||||||
|
size = Vector3(2, 2, 2)
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_k07no"]
|
||||||
|
size = Vector3(2, 2, 2)
|
||||||
|
|
||||||
|
[node name="Building" type="StaticBody3D"]
|
||||||
|
script = ExtResource("1_k07no")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
|
mesh = SubResource("BoxMesh_cee1v")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
|
shape = SubResource("BoxShape3D_k07no")
|
||||||
|
|
||||||
|
[node name="NavigationObstacle3D" type="NavigationObstacle3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
|
radius = 1.0
|
||||||
|
vertices = PackedVector3Array(-1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1)
|
||||||
|
affect_navigation_mesh = true
|
||||||
|
carve_navigation_mesh = true
|
||||||
|
use_3d_avoidance = true
|
|
@ -0,0 +1,25 @@
|
||||||
|
[gd_scene load_steps=6 format=3 uid="uid://c6e1nifka3h4v"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b1fnsl3k1mo5c" path="res://objects/buildings/building.tscn" id="1_hxugg"]
|
||||||
|
[ext_resource type="Script" uid="uid://bshiyw2k3op02" path="res://scripts/building_components/consumer.gd" id="4_dx8de"]
|
||||||
|
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="5_p3dou"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_evfwj"]
|
||||||
|
albedo_color = Color(0.023159, 1, 0, 1)
|
||||||
|
|
||||||
|
[sub_resource type="BoxMesh" id="BoxMesh_3h7kv"]
|
||||||
|
material = SubResource("StandardMaterial3D_evfwj")
|
||||||
|
size = Vector3(2, 2, 2)
|
||||||
|
|
||||||
|
[node name="Processor" instance=ExtResource("1_hxugg")]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" parent="." index="0"]
|
||||||
|
mesh = SubResource("BoxMesh_3h7kv")
|
||||||
|
|
||||||
|
[node name="Consumer" type="Node" parent="." index="3"]
|
||||||
|
script = ExtResource("4_dx8de")
|
||||||
|
metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
||||||
|
|
||||||
|
[node name="Producer" type="Node" parent="." index="4"]
|
||||||
|
script = ExtResource("5_p3dou")
|
||||||
|
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
|
@ -33,7 +33,6 @@ max_speed = 5.0
|
||||||
path_desired_distance = 0.5
|
path_desired_distance = 0.5
|
||||||
target_desired_distance = 0.5
|
target_desired_distance = 0.5
|
||||||
path_max_distance = 1.01
|
path_max_distance = 1.01
|
||||||
avoidance_enabled = true
|
|
||||||
max_speed = 5.0
|
max_speed = 5.0
|
||||||
debug_enabled = true
|
debug_enabled = true
|
||||||
debug_path_custom_color = Color(1, 0, 0.0808306, 1)
|
debug_path_custom_color = Color(1, 0, 0.0808306, 1)
|
||||||
|
@ -46,3 +45,8 @@ mesh = SubResource("QuadMesh_i5arm")
|
||||||
|
|
||||||
[node name="ShapeCast3D" type="ShapeCast3D" parent="."]
|
[node name="ShapeCast3D" type="ShapeCast3D" parent="."]
|
||||||
shape = SubResource("SphereShape3D_a202f")
|
shape = SubResource("SphereShape3D_a202f")
|
||||||
|
|
||||||
|
[node name="Label3D" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.668082, 0)
|
||||||
|
billboard = 1
|
||||||
|
text = "blablabla"
|
||||||
|
|
|
@ -45,6 +45,20 @@ version_control/autoload_on_startup=true
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/PathMesh3D/plugin.cfg", "res://addons/git_describe/plugin.cfg", "res://addons/resources_spreadsheet_view/plugin.cfg")
|
enabled=PackedStringArray("res://addons/PathMesh3D/plugin.cfg", "res://addons/git_describe/plugin.cfg", "res://addons/resources_spreadsheet_view/plugin.cfg")
|
||||||
|
|
||||||
|
[layer_names]
|
||||||
|
|
||||||
|
3d_render/layer_1="Terrain"
|
||||||
|
3d_render/layer_2="Buildings"
|
||||||
|
3d_render/layer_3="Units"
|
||||||
|
3d_physics/layer_1="Terrain"
|
||||||
|
3d_navigation/layer_1="Enemies Small"
|
||||||
|
3d_physics/layer_2="Buildings"
|
||||||
|
3d_navigation/layer_2="Enemies Large"
|
||||||
|
3d_physics/layer_3="Enemies"
|
||||||
|
3d_navigation/layer_3="Citizens"
|
||||||
|
3d_physics/layer_4="Citizens"
|
||||||
|
3d_physics/layer_5="Projectiles"
|
||||||
|
|
||||||
[navigation]
|
[navigation]
|
||||||
|
|
||||||
3d/default_edge_connection_margin=0.6
|
3d/default_edge_connection_margin=0.6
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
extends Node
|
||||||
|
class_name Building
|
||||||
|
|
||||||
|
@export var max_hp: int = 100
|
||||||
|
|
||||||
|
enum BuildState {
|
||||||
|
UNPLACED,
|
||||||
|
BUILDING,
|
||||||
|
READY,
|
||||||
|
DESTROYED
|
||||||
|
}
|
||||||
|
|
||||||
|
var hp: int = max_hp
|
||||||
|
|
||||||
|
var build_state: BuildState = BuildState.BUILDING:
|
||||||
|
set(state):
|
||||||
|
build_state = state
|
||||||
|
|
||||||
|
func is_functional() -> bool:
|
||||||
|
return build_state == BuildState.READY
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dvgo3kpjr2mmj
|
|
@ -0,0 +1,42 @@
|
||||||
|
extends Node
|
||||||
|
class_name Consumer
|
||||||
|
signal item_added(item: Item)
|
||||||
|
|
||||||
|
@export var accepted_items: Array[Item] = []
|
||||||
|
@export var storage_size: int = 4
|
||||||
|
@export var max_inputs: int = 1
|
||||||
|
|
||||||
|
var storage_total: int = 0
|
||||||
|
var storage: Dictionary[Item, int] = {}
|
||||||
|
|
||||||
|
func can_accept_item(item: Item) -> bool:
|
||||||
|
return (storage_total < storage_size) and (accepted_items.has(item) or accepted_items.is_empty())
|
||||||
|
|
||||||
|
func offer_item(item: Item) -> bool:
|
||||||
|
if !can_accept_item(item):
|
||||||
|
return false
|
||||||
|
storage_total += 1
|
||||||
|
var old_count: int = storage.get(item, 0)
|
||||||
|
storage.set(item, old_count + 1)
|
||||||
|
item_added.emit(item)
|
||||||
|
return true
|
||||||
|
|
||||||
|
func check_storage_for_item(item: Item) -> bool:
|
||||||
|
return check_storage_for_items({item:1})
|
||||||
|
|
||||||
|
func check_storage_for_items(items: Dictionary[Item, int]) -> bool:
|
||||||
|
for item in items.keys():
|
||||||
|
if storage.get(item, 0) < items[item]:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
func take_item_from_storage(item: Item) -> bool:
|
||||||
|
return take_items_from_storage({item: 1})
|
||||||
|
|
||||||
|
func take_items_from_storage(items: Dictionary[Item, int]) -> bool:
|
||||||
|
if !check_storage_for_items(items):
|
||||||
|
return false
|
||||||
|
for item in items.keys():
|
||||||
|
var old_count: int = storage.get(item, 0)
|
||||||
|
storage.set(item, old_count - items[item])
|
||||||
|
return true
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bshiyw2k3op02
|
|
@ -0,0 +1,29 @@
|
||||||
|
extends Node
|
||||||
|
class_name Producer
|
||||||
|
|
||||||
|
@export var output_period: float = 0.1
|
||||||
|
@export var max_outputs: int = 1
|
||||||
|
|
||||||
|
var consumers: Array[Consumer]
|
||||||
|
var next_consumer_idx: int = 0
|
||||||
|
#var output_timer: float = 0.0
|
||||||
|
#var output_item: Item
|
||||||
|
|
||||||
|
#func _process(delta: float) -> void:
|
||||||
|
#output_timer += delta
|
||||||
|
#if output_timer >= output_period:
|
||||||
|
#output_timer -= output_period
|
||||||
|
#output()
|
||||||
|
|
||||||
|
func send_item(item: Item) -> bool:
|
||||||
|
if consumers.is_empty():
|
||||||
|
return false
|
||||||
|
next_consumer_idx += 1
|
||||||
|
if next_consumer_idx >= consumers.size():
|
||||||
|
next_consumer_idx = 0
|
||||||
|
|
||||||
|
var consumer: Consumer = consumers[next_consumer_idx]
|
||||||
|
var accepted: bool = consumer.offer_item(item)
|
||||||
|
return accepted
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c4fquatkjmsgu
|
|
@ -0,0 +1,58 @@
|
||||||
|
extends Path3D
|
||||||
|
|
||||||
|
@export var speed: float = 1.0
|
||||||
|
@export var item_offset: Vector3 = Vector3(0,1,0)
|
||||||
|
|
||||||
|
var transported_items: Dictionary[Item, PackedFloat64Array] = {}
|
||||||
|
|
||||||
|
@onready var producer: Producer = $Producer
|
||||||
|
@onready var multimesh: MultiMeshInstance3D = $MultiMeshInstance3D
|
||||||
|
|
||||||
|
var test_timer: float = 0
|
||||||
|
@onready var test_item: Item = load("res://items/metal.tres")
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
test_timer += delta
|
||||||
|
if test_timer >= 2.0:
|
||||||
|
test_timer -= 2.0
|
||||||
|
add_item(test_item)
|
||||||
|
|
||||||
|
var belt_moving: bool = check_items_at_end()
|
||||||
|
if belt_moving:
|
||||||
|
for transported_item_type in transported_items.keys():
|
||||||
|
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
||||||
|
multimesh.multimesh.instance_count = offsets.size()
|
||||||
|
for i in range(offsets.size()):
|
||||||
|
offsets[i] += (delta * speed)
|
||||||
|
position_item(i, transported_item_type, offsets[i])
|
||||||
|
|
||||||
|
func add_item(item: Item) -> void:
|
||||||
|
var offsets: PackedFloat64Array
|
||||||
|
if transported_items.has(item):
|
||||||
|
offsets = transported_items[item]
|
||||||
|
else:
|
||||||
|
offsets = []
|
||||||
|
offsets.append(0.0)
|
||||||
|
transported_items[item] = offsets
|
||||||
|
|
||||||
|
func check_items_at_end() -> bool:
|
||||||
|
var length: float = curve.get_baked_length()
|
||||||
|
var belt_moving: bool = true
|
||||||
|
for transported_item_type in transported_items.keys():
|
||||||
|
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
||||||
|
var to_delete: Array[int] = []
|
||||||
|
for i in range(offsets.size()):
|
||||||
|
if offsets[i] >= length:
|
||||||
|
var sent: bool = producer.send_item(transported_item_type)
|
||||||
|
if !sent:
|
||||||
|
belt_moving = false
|
||||||
|
else:
|
||||||
|
to_delete.append(i)
|
||||||
|
for d in to_delete:
|
||||||
|
offsets.remove_at(d)
|
||||||
|
return belt_moving
|
||||||
|
|
||||||
|
func position_item(instance: int, item: Item, offset: float) -> void:
|
||||||
|
var trans: Transform3D = curve.sample_baked_with_rotation(offset).translated_local(item_offset)
|
||||||
|
multimesh.multimesh.set_instance_transform(instance, trans)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cnoyykkcidp1d
|
|
@ -0,0 +1,24 @@
|
||||||
|
extends Building
|
||||||
|
|
||||||
|
@export var ingredients: Dictionary[Item, int] = {}
|
||||||
|
@export var process_time: float = 1.0
|
||||||
|
@export var created_item: Item
|
||||||
|
|
||||||
|
var process_timer: float = 0.0
|
||||||
|
var processing: bool = false
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if is_functional():
|
||||||
|
if !processing:
|
||||||
|
processing = consume_ingredients()
|
||||||
|
if processing:
|
||||||
|
process_timer += delta
|
||||||
|
if process_timer >= process_time:
|
||||||
|
process_timer -= process_time
|
||||||
|
produce_item()
|
||||||
|
|
||||||
|
func consume_ingredients() -> bool:
|
||||||
|
return $Consumer.take_items_from_storage(ingredients)
|
||||||
|
|
||||||
|
func produce_item() -> void:
|
||||||
|
$Producer.set_output_item(created_item)
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c3bqfgoof2c83
|
|
@ -0,0 +1,6 @@
|
||||||
|
extends Resource
|
||||||
|
class_name Item
|
||||||
|
|
||||||
|
@export var icon: Texture2D
|
||||||
|
@export var name: String
|
||||||
|
@export var model: Mesh
|
|
@ -0,0 +1 @@
|
||||||
|
uid://kcdpck5ufgcc
|
|
@ -3,37 +3,62 @@ class_name Unit
|
||||||
|
|
||||||
@export var movement_force: float = 100
|
@export var movement_force: float = 100
|
||||||
@export var max_speed: float = 100
|
@export var max_speed: float = 100
|
||||||
|
@export var minimum_progress_rate: float = 1.0
|
||||||
|
@export var stuck_time: float = 1.0
|
||||||
|
|
||||||
var target_velocity: Vector3 = Vector3()
|
var target_velocity: Vector3 = Vector3()
|
||||||
|
var last_distance_to_target: float = 0.0
|
||||||
|
var stuck_timer: float = 0.0
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
$NavigationAgent3D.connect("velocity_computed", avoidance_velocity_computed)
|
#$NavigationAgent3D.connect("velocity_computed", avoidance_velocity_computed)
|
||||||
|
pass
|
||||||
|
|
||||||
func avoidance_velocity_computed(velocity: Vector3) -> void:
|
func avoidance_velocity_computed(velocity: Vector3) -> void:
|
||||||
if velocity != target_velocity:
|
if velocity != target_velocity:
|
||||||
DebugDraw3D.draw_line(global_position, global_position + velocity, Color.ORANGE)
|
#DebugDraw3D.draw_line(global_position, global_position + velocity, Color.ORANGE)
|
||||||
#print("Avoidance issued!")
|
#print("Avoidance issued!")
|
||||||
target_velocity = velocity
|
target_velocity = velocity
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
if $NavigationAgent3D.is_target_reached() or $NavigationAgent3D.target_position.is_zero_approx():
|
if $NavigationAgent3D.is_target_reached() \
|
||||||
|
or $NavigationAgent3D.target_position.is_zero_approx() \
|
||||||
|
or !$NavigationAgent3D.is_target_reachable():
|
||||||
$NavigationAgent3D.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
|
$NavigationAgent3D.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
|
||||||
|
last_distance_to_target = $NavigationAgent3D.distance_to_target()
|
||||||
else:
|
else:
|
||||||
#DebugDraw3D.draw_sphere($NavigationAgent3D.target_position, 0.5, Color.RED)
|
var distance_to_target: float = $NavigationAgent3D.distance_to_target()
|
||||||
|
var progress_rate: float = (last_distance_to_target - distance_to_target) / delta
|
||||||
|
$Label3D.text = "Prog: %f" % progress_rate
|
||||||
|
last_distance_to_target = distance_to_target
|
||||||
|
if progress_rate < minimum_progress_rate:
|
||||||
|
$Label3D.modulate = Color.RED
|
||||||
|
stuck_timer += delta
|
||||||
|
if stuck_timer >= stuck_time:
|
||||||
|
unstuck()
|
||||||
|
else:
|
||||||
|
$Label3D.modulate = Color.WHITE
|
||||||
|
stuck_timer = 0
|
||||||
|
DebugDraw3D.draw_sphere($NavigationAgent3D.target_position, 0.5, Color.RED)
|
||||||
var next_point: Vector3 = $NavigationAgent3D.get_next_path_position()
|
var next_point: Vector3 = $NavigationAgent3D.get_next_path_position()
|
||||||
DebugDraw3D.draw_sphere(next_point, 0.1, Color.YELLOW)
|
DebugDraw3D.draw_sphere(next_point, 0.1, Color.YELLOW)
|
||||||
var direction: Vector3 = (next_point - global_position).normalized()
|
var direction: Vector3 = (next_point - global_position).normalized()
|
||||||
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
|
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
|
||||||
var target_velocity: Vector3 = direction * max_speed
|
target_velocity= direction * max_speed
|
||||||
$NavigationAgent3D.velocity = target_velocity
|
#$NavigationAgent3D.velocity = target_velocity
|
||||||
DebugDraw3D.draw_line(global_position, global_position + target_velocity, Color.MAGENTA)
|
#DebugDraw3D.draw_line(global_position, global_position + target_velocity, Color.MAGENTA)
|
||||||
|
#DebugDraw3D.draw_text(global_position + Vector3(0,1,0), "%f" % $NavigationAgent3D.distance_to_target())
|
||||||
|
|
||||||
|
func unstuck() -> void:
|
||||||
|
# teleport to next path point
|
||||||
|
global_position = $NavigationAgent3D.get_next_path_position()
|
||||||
|
stuck_timer = 0
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if $ShapeCast3D.is_colliding():
|
if $ShapeCast3D.is_colliding():
|
||||||
var force_direction: Vector3 = (target_velocity-linear_velocity)
|
var force_direction: Vector3 = (target_velocity-linear_velocity)
|
||||||
var normal: Vector3 = $ShapeCast3D.get_collision_normal(0)
|
var normal: Vector3 = $ShapeCast3D.get_collision_normal(0)
|
||||||
DebugDraw3D.draw_line(global_position, global_position + normal, Color.DODGER_BLUE)
|
#DebugDraw3D.draw_line(global_position, global_position + normal, Color.DODGER_BLUE)
|
||||||
var force: Vector3 = (force_direction * movement_force).slide(normal)
|
var force: Vector3 = (force_direction * movement_force).slide(normal)
|
||||||
DebugDraw3D.draw_line(global_position, global_position + force, Color.GREEN)
|
#DebugDraw3D.draw_line(global_position, global_position + force, Color.GREEN)
|
||||||
apply_central_force(force)
|
apply_central_force(force)
|
||||||
|
|
57
tiles.tscn
57
tiles.tscn
|
@ -1,9 +1,4 @@
|
||||||
[gd_scene load_steps=17 format=3 uid="uid://bexxobgiojrfa"]
|
[gd_scene load_steps=9 format=3 uid="uid://bexxobgiojrfa"]
|
||||||
|
|
||||||
[ext_resource type="ArrayMesh" uid="uid://bs13eo8off8ee" path="res://assets/models/Ramp Corner Inner.obj" id="1_k6t24"]
|
|
||||||
[ext_resource type="ArrayMesh" uid="uid://ca1wobe3qgakn" path="res://assets/models/Ramp Corner Inner Nav.obj" id="2_d6bvg"]
|
|
||||||
[ext_resource type="ArrayMesh" uid="uid://1ud15exgl668" path="res://assets/models/Ramp Corner Outer.obj" id="3_7ivye"]
|
|
||||||
[ext_resource type="ArrayMesh" uid="uid://bai5bvubpu4ec" path="res://assets/models/Ramp Corner Outer Nav.obj" id="4_vra4g"]
|
|
||||||
|
|
||||||
[sub_resource type="BoxMesh" id="BoxMesh_qra7f"]
|
[sub_resource type="BoxMesh" id="BoxMesh_qra7f"]
|
||||||
size = Vector3(2, 1, 2)
|
size = Vector3(2, 1, 2)
|
||||||
|
@ -32,7 +27,7 @@ size = Vector3(2, 1, 2)
|
||||||
points = PackedVector3Array(-1, -0.5, -1, -1, 0.5, -1, 1, -0.5, -1, -1, -0.5, 1, -1, 0.5, 1, 1, -0.5, 1)
|
points = PackedVector3Array(-1, -0.5, -1, -1, 0.5, -1, 1, -0.5, -1, -1, -0.5, 1, -1, 0.5, 1, 1, -0.5, 1)
|
||||||
|
|
||||||
[sub_resource type="NavigationMesh" id="NavigationMesh_7h0kd"]
|
[sub_resource type="NavigationMesh" id="NavigationMesh_7h0kd"]
|
||||||
vertices = PackedVector3Array(-0.735052, 0.760437, -0.75, -0.735052, 0.760437, 0.75, 0.764948, 0.010437, 0.75, 0.764948, 0.010437, -0.75)
|
vertices = PackedVector3Array(-0.735052, 0.760437, -0.75, -0.735052, 0.760437, 0.75, 0.764948, 0.0104373, 0.75, 0.764948, 0.0104373, -0.75)
|
||||||
polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)]
|
polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)]
|
||||||
agent_radius = 0.2
|
agent_radius = 0.2
|
||||||
|
|
||||||
|
@ -40,22 +35,6 @@ agent_radius = 0.2
|
||||||
size = Vector2(2.2, 2)
|
size = Vector2(2.2, 2)
|
||||||
orientation = 1
|
orientation = 1
|
||||||
|
|
||||||
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_7ivye"]
|
|
||||||
data = PackedVector3Array(-1, 0.5, -1, -1, -0.5, 1, -1, -0.5, -1, 1, 0.5, -1, 1, -0.5, -1, 1, 0.5, 1, 1, 0.5, 1, 1, -0.5, -1, 1, -0.5, 1, 1, 0.5, 1, 1, -0.5, 1, -1, -0.5, 1, 1, -0.5, -1, -1, -0.5, -1, 1, -0.5, 1, 1, -0.5, 1, -1, -0.5, -1, -1, -0.5, 1, -1, 0.5, -1, -1, -0.5, -1, 1, 0.5, -1, 1, 0.5, -1, -1, -0.5, -1, 1, -0.5, -1, -1, 0.5, -1, 1, 0.5, -1, -1, -0.5, 1, 1, 0.5, -1, 1, 0.5, 1, -1, -0.5, 1)
|
|
||||||
|
|
||||||
[sub_resource type="NavigationMesh" id="NavigationMesh_vra4g"]
|
|
||||||
vertices = PackedVector3Array(-0.75, 0.75, -0.75, -0.75, 0, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, -0.75)
|
|
||||||
polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)]
|
|
||||||
agent_radius = 0.2
|
|
||||||
|
|
||||||
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_xlp04"]
|
|
||||||
points = PackedVector3Array(1, -0.5, -1, -1, -0.5, 1, 1, 0.5, 1, 1, -0.5, 1)
|
|
||||||
|
|
||||||
[sub_resource type="NavigationMesh" id="NavigationMesh_341ea"]
|
|
||||||
vertices = PackedVector3Array(-1, 0, 0.75, 1, 0.75, 1, 1, 0, -1)
|
|
||||||
polygons = [PackedInt32Array(2, 1, 0)]
|
|
||||||
agent_radius = 0.0
|
|
||||||
|
|
||||||
[node name="Tiles" type="Node3D"]
|
[node name="Tiles" type="Node3D"]
|
||||||
|
|
||||||
[node name="Cube" type="MeshInstance3D" parent="."]
|
[node name="Cube" type="MeshInstance3D" parent="."]
|
||||||
|
@ -73,7 +52,7 @@ navigation_mesh = SubResource("NavigationMesh_qra7f")
|
||||||
mesh = SubResource("QuadMesh_7h0kd")
|
mesh = SubResource("QuadMesh_7h0kd")
|
||||||
|
|
||||||
[node name="Ramp" type="MeshInstance3D" parent="."]
|
[node name="Ramp" type="MeshInstance3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.99928, -0.00256312, 0.000191689)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.40447, -0.00256312, 0.000191689)
|
||||||
mesh = SubResource("PrismMesh_qra7f")
|
mesh = SubResource("PrismMesh_qra7f")
|
||||||
|
|
||||||
[node name="StaticBody3D" type="StaticBody3D" parent="Ramp"]
|
[node name="StaticBody3D" type="StaticBody3D" parent="Ramp"]
|
||||||
|
@ -87,33 +66,3 @@ navigation_mesh = SubResource("NavigationMesh_7h0kd")
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ramp/NavigationRegion3D"]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ramp/NavigationRegion3D"]
|
||||||
transform = Transform3D(0.895502, 0.445057, 0, -0.445057, 0.895502, 0, 0, 0, 1, 0, 0, 0)
|
transform = Transform3D(0.895502, 0.445057, 0, -0.445057, 0.895502, 0, 0, 0, 1, 0, 0, 0)
|
||||||
mesh = SubResource("QuadMesh_k6t24")
|
mesh = SubResource("QuadMesh_k6t24")
|
||||||
|
|
||||||
[node name="Ramp Inner Corner" type="MeshInstance3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0, 0)
|
|
||||||
mesh = ExtResource("1_k6t24")
|
|
||||||
|
|
||||||
[node name="StaticBody3D" type="StaticBody3D" parent="Ramp Inner Corner"]
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ramp Inner Corner/StaticBody3D"]
|
|
||||||
shape = SubResource("ConcavePolygonShape3D_7ivye")
|
|
||||||
|
|
||||||
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="Ramp Inner Corner"]
|
|
||||||
navigation_mesh = SubResource("NavigationMesh_vra4g")
|
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ramp Inner Corner/NavigationRegion3D"]
|
|
||||||
mesh = ExtResource("2_d6bvg")
|
|
||||||
|
|
||||||
[node name="Ramp Outer Corner" type="MeshInstance3D" parent="."]
|
|
||||||
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 2, 0, 2)
|
|
||||||
mesh = ExtResource("3_7ivye")
|
|
||||||
|
|
||||||
[node name="StaticBody3D" type="StaticBody3D" parent="Ramp Outer Corner"]
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ramp Outer Corner/StaticBody3D"]
|
|
||||||
shape = SubResource("ConvexPolygonShape3D_xlp04")
|
|
||||||
|
|
||||||
[node name="NavigationRegion3D" type="NavigationRegion3D" parent="Ramp Outer Corner"]
|
|
||||||
navigation_mesh = SubResource("NavigationMesh_341ea")
|
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ramp Outer Corner/NavigationRegion3D"]
|
|
||||||
mesh = ExtResource("4_vra4g")
|
|
||||||
|
|
Loading…
Reference in New Issue