Compare commits
10 Commits
components
...
swarm_engi
| Author | SHA1 | Date | |
|---|---|---|---|
| 5301cfa598 | |||
| 19cc3a1888 | |||
| 3965b3603a | |||
| 4b53993237 | |||
| 3df81364d6 | |||
| dbd4f668aa | |||
| 641b069cb0 | |||
| 6fecc5632c | |||
| 44280e9202 | |||
| b9c94eeed6 |
BIN
assets/spider/result.bin
Normal file
BIN
assets/spider/result.bin
Normal file
Binary file not shown.
33434
assets/spider/result.gltf
Normal file
33434
assets/spider/result.gltf
Normal file
File diff suppressed because it is too large
Load Diff
53
assets/spider/result.gltf.import
Normal file
53
assets/spider/result.gltf.import
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://bcsjr6kydgdqy"
|
||||||
|
path="res://.godot/imported/result.gltf-fa6e7d401ecc486ebc1efbad267cda09.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/spider/result.gltf"
|
||||||
|
dest_files=["res://.godot/imported/result.gltf-fa6e7d401ecc486ebc1efbad267cda09.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=1.0
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
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={
|
||||||
|
"meshes": {
|
||||||
|
"result_Cube": {
|
||||||
|
"generate/lightmap_uv": 0,
|
||||||
|
"generate/lods": 0,
|
||||||
|
"generate/shadow_meshes": 1,
|
||||||
|
"lods/normal_merge_angle": 60.0,
|
||||||
|
"lods/normal_split_angle": 25.0,
|
||||||
|
"save_to_file/enabled": true,
|
||||||
|
"save_to_file/path": "res://assets/spider/spider_mesh.res"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"PATH:RootNode/SpiderArmature/Skeleton3D": {
|
||||||
|
"rest_pose/external_animation_library": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gltf/naming_version=1
|
||||||
|
gltf/embedded_image_handling=1
|
||||||
BIN
assets/spider/spider_mesh.res
Normal file
BIN
assets/spider/spider_mesh.res
Normal file
Binary file not shown.
@@ -17,6 +17,9 @@ var not_dead := true
|
|||||||
@export_multiline var death_message : Array[String]
|
@export_multiline var death_message : Array[String]
|
||||||
#@onready var color_rect: ColorRect = $CanvasLayer/ColorRect
|
#@onready var color_rect: ColorRect = $CanvasLayer/ColorRect
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
DebugDraw3D.draw_sphere(position, .5)
|
||||||
|
|
||||||
func handle_dying():
|
func handle_dying():
|
||||||
not_dead = false
|
not_dead = false
|
||||||
#weapon_slot_2.queue_free()
|
#weapon_slot_2.queue_free()
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ config/icon="res://icon.svg"
|
|||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
MathUtils="*res://singeltons/MathUtils.gd"
|
DebugUi="*res://scenes/debug_ui/debug_ui.tscn"
|
||||||
DamageHandler="*res://singeltons/DamageHandler.gd"
|
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
@@ -79,6 +78,11 @@ turn_right={
|
|||||||
"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)
|
"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)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
show_debug_ui={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"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":80,"key_label":0,"unicode":112,"location":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[physics]
|
[physics]
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="EntityStats" load_steps=12 format=3 uid="uid://qcjre5wwbrs3"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://scripts/resources/Stats/ArmorStat.gd" id="1_c7135"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/resources/Entity/EntityStats.gd" id="1_xti0a"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/resources/Stats/HealthStat.gd" id="2_hsnpy"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/resources/Stats/MaxHealthStat.gd" id="3_26tso"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/resources/Stats/MovementSpeedStat.gd" id="4_goc2a"]
|
|
||||||
[ext_resource type="Script" path="res://scripts/resources/Stats/ShieldStat.gd" id="6_rncik"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_vbm44"]
|
|
||||||
script = ExtResource("1_c7135")
|
|
||||||
_value = 0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_nyvlf"]
|
|
||||||
script = ExtResource("2_hsnpy")
|
|
||||||
_value = 0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_pxuuc"]
|
|
||||||
script = ExtResource("3_26tso")
|
|
||||||
_value = 10
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_vs6ff"]
|
|
||||||
script = ExtResource("4_goc2a")
|
|
||||||
_value = 0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_r5hb1"]
|
|
||||||
script = ExtResource("6_rncik")
|
|
||||||
_value = 0
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1_xti0a")
|
|
||||||
max_health = SubResource("Resource_pxuuc")
|
|
||||||
health = SubResource("Resource_nyvlf")
|
|
||||||
armor = SubResource("Resource_vbm44")
|
|
||||||
shield = SubResource("Resource_r5hb1")
|
|
||||||
movementSpeed = SubResource("Resource_vs6ff")
|
|
||||||
@@ -9,14 +9,5 @@ shadow_enabled = true
|
|||||||
[node name="CSGBox3D" type="CSGBox3D" parent="."]
|
[node name="CSGBox3D" type="CSGBox3D" parent="."]
|
||||||
transform = Transform3D(0.804543, 0.301369, -0.511748, -0.471444, 0.848123, -0.241718, 0.361179, 0.435734, 0.824431, 0, 0, 0)
|
transform = Transform3D(0.804543, 0.301369, -0.511748, -0.471444, 0.848123, -0.241718, 0.361179, 0.435734, 0.824431, 0, 0, 0)
|
||||||
|
|
||||||
[node name="CSGBox3D" type="CSGBox3D" parent="CSGBox3D"]
|
|
||||||
transform = Transform3D(0.804543, 0.301369, -0.511748, -0.471444, 0.848123, -0.241718, 0.361179, 0.435734, 0.824431, 0, 0, 0)
|
|
||||||
|
|
||||||
[node name="CSGBox3D" type="CSGBox3D" parent="CSGBox3D/CSGBox3D"]
|
|
||||||
transform = Transform3D(0.804543, 0.301369, -0.511748, -0.471444, 0.848123, -0.241718, 0.361179, 0.435734, 0.824431, 0, 0, 0)
|
|
||||||
|
|
||||||
[node name="CSGBox3D" type="CSGBox3D" parent="CSGBox3D/CSGBox3D/CSGBox3D"]
|
|
||||||
transform = Transform3D(0.804543, 0.301369, -0.511748, -0.471444, 0.848123, -0.241718, 0.361179, 0.435734, 0.824431, 0, 0, 0)
|
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="."]
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 0.901077, 0.433659, 0, -0.433659, 0.901077, 0, 1.21776, 2.12747)
|
transform = Transform3D(1, 0, 0, 0, 0.901077, 0.433659, 0, -0.433659, 0.901077, 0, 1.21776, 2.12747)
|
||||||
|
|||||||
13
scenes/debug_ui/debug_ui.gd
Normal file
13
scenes/debug_ui/debug_ui.gd
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
extends Control
|
||||||
|
|
||||||
|
@export var show_debug_ui: bool = true
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event.is_action_pressed("show_debug_ui"):
|
||||||
|
show_debug_ui = !show_debug_ui
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if show_debug_ui:
|
||||||
|
DebugDraw2D.set_text("Frames drawn", Engine.get_frames_drawn())
|
||||||
|
DebugDraw2D.set_text("FPS", Engine.get_frames_per_second())
|
||||||
|
DebugDraw2D.set_text("delta", delta)
|
||||||
12
scenes/debug_ui/debug_ui.tscn
Normal file
12
scenes/debug_ui/debug_ui.tscn
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://clcnavxmm7eae"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/debug_ui/debug_ui.gd" id="1_24u3s"]
|
||||||
|
|
||||||
|
[node name="DebugUi" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_24u3s")
|
||||||
@@ -1 +0,0 @@
|
|||||||
class_name Enemie extends Entity
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
class_name Entity extends Node3D
|
|
||||||
|
|
||||||
|
|
||||||
var stats: EntityStats
|
|
||||||
var equipments: Array[Equipment]
|
|
||||||
signal died_event(entity: Entity)
|
|
||||||
|
|
||||||
func init_entity(stats: EntityStats):
|
|
||||||
self.stats = stats;
|
|
||||||
|
|
||||||
func equip(newEquipment: Equipment)-> void:
|
|
||||||
equipments.append(newEquipment)
|
|
||||||
|
|
||||||
func unequip(equipmentToRemove: Equipment)-> void:
|
|
||||||
equipments.erase(equipmentToRemove)
|
|
||||||
|
|
||||||
|
|
||||||
func get_health()->int:
|
|
||||||
return stats.health.value
|
|
||||||
|
|
||||||
func get_shield()->int:
|
|
||||||
return stats.shield.value
|
|
||||||
|
|
||||||
func reduce_shield(damage: int):
|
|
||||||
stats.shield.value -= damage
|
|
||||||
if stats.shield.value <= 0:
|
|
||||||
stats.shield.value = 0
|
|
||||||
|
|
||||||
func increase_health(additional_health: int):
|
|
||||||
stats.health.value += additional_health
|
|
||||||
if stats.health.value > get_max_health():
|
|
||||||
stats.health.value = get_max_health()
|
|
||||||
|
|
||||||
func reduce_health(damage: int):
|
|
||||||
stats.health.value -= damage
|
|
||||||
if stats.health.value <= 0:
|
|
||||||
died()
|
|
||||||
|
|
||||||
func died():
|
|
||||||
died_event.emit(self)
|
|
||||||
|
|
||||||
func get_max_health()->int:
|
|
||||||
var max_health = stats.max_health
|
|
||||||
for equipment in equipments:
|
|
||||||
max_health += equipment.get_max_health()
|
|
||||||
return max_health
|
|
||||||
|
|
||||||
func get_armor()->int:
|
|
||||||
var armor = stats.armor
|
|
||||||
for equipment in equipments:
|
|
||||||
armor += equipment.get_armor()
|
|
||||||
return armor
|
|
||||||
|
|
||||||
func get_max_Shield()->int:
|
|
||||||
var shield = stats.shield
|
|
||||||
for equipment in equipments:
|
|
||||||
shield += equipment.get_max_shield()
|
|
||||||
return shield
|
|
||||||
|
|
||||||
func get_movement_speed()->int:
|
|
||||||
var movement_speed = stats.movement_speed
|
|
||||||
for equipment in equipments:
|
|
||||||
movement_speed += equipment.get_evement_speed()
|
|
||||||
return movement_speed
|
|
||||||
|
|
||||||
func get_damage()->int:
|
|
||||||
var damage = 0
|
|
||||||
for equipment in equipments:
|
|
||||||
damage += equipment.get_damage()
|
|
||||||
return damage
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
class_name PlayerCharacter extends Entity
|
|
||||||
|
|
||||||
var mech: Mech
|
|
||||||
|
|
||||||
func init_player_character(stats: EntityStats, mech: Mech):
|
|
||||||
init_entity(stats)
|
|
||||||
self.mech = mech;
|
|
||||||
|
|
||||||
func get_max_health() -> int:
|
|
||||||
return super() + mech.get_max_health()
|
|
||||||
|
|
||||||
func get_armor() -> int:
|
|
||||||
return super() + mech.get_armor()
|
|
||||||
|
|
||||||
func get_max_Shield() -> int:
|
|
||||||
return super() + mech.get_shield()
|
|
||||||
|
|
||||||
func get_movement_speed() -> int:
|
|
||||||
return super() + mech.get_movement_speed()
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
class_name Attachment extends Node3D
|
|
||||||
|
|
||||||
|
|
||||||
var stats: AttachmentStats
|
|
||||||
|
|
||||||
func init_attachment(stats: AttachmentStats):
|
|
||||||
self.stats = stats
|
|
||||||
|
|
||||||
func get_damage()->int:
|
|
||||||
return stats.damage.value
|
|
||||||
|
|
||||||
func get_fire_rate()->int:
|
|
||||||
return stats.fire_rate.value
|
|
||||||
|
|
||||||
func get_hit_effects()-> Array[Effect]:
|
|
||||||
return stats.hit_effects.value
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
class_name Equipment extends Node3D
|
|
||||||
|
|
||||||
|
|
||||||
var stats: EquipmentStats
|
|
||||||
|
|
||||||
func init_equipment(stats: EquipmentStats):
|
|
||||||
self.stats = stats;
|
|
||||||
|
|
||||||
func get_armor()-> int:
|
|
||||||
return stats.armor.value
|
|
||||||
|
|
||||||
func get_max_health()-> int:
|
|
||||||
return stats.max_health.value
|
|
||||||
|
|
||||||
func get_max_shield()-> int:
|
|
||||||
return stats.max_shield.value
|
|
||||||
|
|
||||||
func get_evement_speed()-> int:
|
|
||||||
return stats.movementSpeed.value
|
|
||||||
|
|
||||||
func get_damage()-> int:
|
|
||||||
return stats.damage.value
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
class_name Arms extends Equipment
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
class_name Boots extends Equipment
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
class_name Hydraulics extends Equipment
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
extends Node3D
|
|
||||||
|
|
||||||
class_name Mech
|
|
||||||
|
|
||||||
var boots: Boots
|
|
||||||
var arms: Arms
|
|
||||||
var hydraulics: Hydraulics
|
|
||||||
|
|
||||||
|
|
||||||
func init_mech(boots: Boots, arms: Arms, hydraulics: Hydraulics):
|
|
||||||
self.boots = boots
|
|
||||||
self.arms = arms
|
|
||||||
self.hydraulics= hydraulics
|
|
||||||
|
|
||||||
func get_max_health()-> int:
|
|
||||||
return boots.get_max_health() +arms.get_max_health()+hydraulics.get_max_health()
|
|
||||||
|
|
||||||
func get_armor()-> int:
|
|
||||||
return boots.get_armor()+arms.get_armor()+hydraulics.get_armor()
|
|
||||||
|
|
||||||
func get_max_shield()-> int:
|
|
||||||
return boots.get_max_shield()+arms.get_max_shield()+hydraulics.get_max_shield()
|
|
||||||
|
|
||||||
func get_damage()-> int:
|
|
||||||
return boots.get_damage()+arms.get_damage()+hydraulics.get_damage()
|
|
||||||
|
|
||||||
func get_movement_speed()-> int:
|
|
||||||
return boots.get_evement_speed()+arms.get_evement_speed()+hydraulics.get_evement_speed()
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
class_name Weapon extends Node3D
|
|
||||||
|
|
||||||
var stats: WeaponStats
|
|
||||||
var attachments: Array[Attachment]
|
|
||||||
|
|
||||||
func init_weapon(stats: WeaponStats):
|
|
||||||
self.stats = stats;
|
|
||||||
|
|
||||||
func attach(newAttachment: Attachment)-> void:
|
|
||||||
attachments.append(newAttachment)
|
|
||||||
|
|
||||||
func unattach(attachmentToRemove: Attachment)-> void:
|
|
||||||
attachments.erase(attachmentToRemove)
|
|
||||||
|
|
||||||
func get_damage()->int:
|
|
||||||
var damage = stats.damage
|
|
||||||
for attachment in attachments:
|
|
||||||
damage += attachment.get_damage()
|
|
||||||
return damage
|
|
||||||
|
|
||||||
func get_fire_rate()->int:
|
|
||||||
var fire_rate = stats.fire_rate
|
|
||||||
for attachment in attachments:
|
|
||||||
fire_rate += attachment.get_fire_rate()
|
|
||||||
return fire_rate
|
|
||||||
|
|
||||||
func get_hit_effects()-> Array[Effect]:
|
|
||||||
var hit_effects = []
|
|
||||||
hit_effects.append_array(stats.hit_effects.value)
|
|
||||||
for attachment in attachments:
|
|
||||||
hit_effects.append_array(attachment.get_hit_effects())
|
|
||||||
return hit_effects
|
|
||||||
|
|
||||||
7
scripts/helper/color_helper.gd
Normal file
7
scripts/helper/color_helper.gd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
extends Resource
|
||||||
|
class_name ColorHelper
|
||||||
|
|
||||||
|
static func get_direction_color(direction: Vector3) -> Color:
|
||||||
|
var angle = atan2(direction.z, direction.x)
|
||||||
|
var hue = (angle / (2.0 * PI)) + 0.5
|
||||||
|
return Color.from_hsv(hue, 1.0, 1.0)
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name Effect
|
|
||||||
|
|
||||||
func apply_effect (orign_entity: Entity, target_entity: Entity)-> void:
|
|
||||||
assert(false)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
class_name HealEffect extends Effect
|
|
||||||
|
|
||||||
@export var heal_amount: int
|
|
||||||
|
|
||||||
func apply_effect (orign_entity: Entity, target_entity: Entity)-> void:
|
|
||||||
target_entity.increase_health(heal_amount)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name EntityResource
|
|
||||||
|
|
||||||
@export var entity_stats: EntityStats
|
|
||||||
@export var entity_scene: PackedScene
|
|
||||||
|
|
||||||
|
|
||||||
func instantiate(parent: Node3D)->Entity:
|
|
||||||
var entity_instance = entity_scene.instantiate() as Entity
|
|
||||||
entity_instance.init_entity(entity_stats)
|
|
||||||
parent.add_child(entity_instance)
|
|
||||||
return entity_instance
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name EntityStats
|
|
||||||
|
|
||||||
@export var max_health: MaxHealthStat
|
|
||||||
@export var health: HealthStat
|
|
||||||
@export var armor: ArmorStat
|
|
||||||
@export var shield: ShieldStat
|
|
||||||
@export var max_shield: MaxShieldStat
|
|
||||||
@export var movementSpeed: MovementSpeedStat
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name EquipmentResource
|
|
||||||
|
|
||||||
@export var name: String
|
|
||||||
@export var equipment_stats: EquipmentStats
|
|
||||||
@export var equipment_scene: PackedScene
|
|
||||||
|
|
||||||
|
|
||||||
func instantiate(parent: Node3D)->Equipment:
|
|
||||||
var equipment_instance = equipment_scene.instantiate() as Equipment
|
|
||||||
equipment_instance.init_Equipment(equipment_stats)
|
|
||||||
parent.add_child(equipment_instance)
|
|
||||||
return equipment_instance
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name EquipmentStats
|
|
||||||
|
|
||||||
@export var max_health: MaxHealthStat
|
|
||||||
@export var armor: ArmorStat
|
|
||||||
@export var max_shield: MaxShieldStat
|
|
||||||
@export var movementSpeed: MovementSpeedStat
|
|
||||||
@export var damage: DamageStat
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
extends MechPartResource
|
|
||||||
|
|
||||||
class_name ArmsResource
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
extends MechPartResource
|
|
||||||
|
|
||||||
class_name BootsResource
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
extends MechPartResource
|
|
||||||
|
|
||||||
class_name HydraulicsResource
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
extends EquipmentResource
|
|
||||||
|
|
||||||
class_name MechPartResource
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name ArmorStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentArmor: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name DamageStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentDamage: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name HitEffectStat
|
|
||||||
|
|
||||||
signal value_changed_signal(effects: Array[Effect])
|
|
||||||
|
|
||||||
@export var _value: Array[Effect]
|
|
||||||
var value: Array[Effect]:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name FireRateStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentFireRate: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name HealthStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentHealth: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name MaxHealthStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentMaxHealth: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name MaxShieldStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentMaxShield: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name MovementSpeedStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentMovementSpeed: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name ShieldStat
|
|
||||||
|
|
||||||
signal value_changed_signal(currentShield: int)
|
|
||||||
|
|
||||||
@export var _value: int
|
|
||||||
var value: int:
|
|
||||||
get:
|
|
||||||
return _value
|
|
||||||
set(new_value):
|
|
||||||
value = new_value;
|
|
||||||
value_changed_signal.emit(_value)
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name AttachmentResource
|
|
||||||
|
|
||||||
@export var attachment_stats: AttachmentStats
|
|
||||||
@export var attachment_scene: PackedScene
|
|
||||||
|
|
||||||
|
|
||||||
func instantiate(parent: Node3D)->Attachment:
|
|
||||||
var attachment_instance = attachment_scene.instantiate() as Attachment
|
|
||||||
attachment_instance.init_Attachment(attachment_stats)
|
|
||||||
parent.add_child(attachment_instance)
|
|
||||||
return attachment_instance
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name AttachmentStats
|
|
||||||
|
|
||||||
@export var damage: DamageStat
|
|
||||||
@export var fire_rate: FireRateStat
|
|
||||||
@export var hit_effects: HitEffectStat
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name WeaponResource
|
|
||||||
|
|
||||||
@export var name: String
|
|
||||||
@export var weapon_stats: WeaponStats
|
|
||||||
@export var weapon_scene: PackedScene
|
|
||||||
|
|
||||||
func instantiate(parent: Node3D)->Weapon:
|
|
||||||
var weapon_instance = weapon_scene.instantiate() as Weapon
|
|
||||||
weapon_instance.init_weapon(weapon_stats)
|
|
||||||
parent.add_child(weapon_instance)
|
|
||||||
return weapon_instance
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
|
|
||||||
class_name WeaponStats
|
|
||||||
|
|
||||||
|
|
||||||
@export var damage: DamageStat
|
|
||||||
@export var fire_rate: FireRateStat
|
|
||||||
@export var hit_effects: HitEffectStat
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
extends Object
|
|
||||||
|
|
||||||
func apply_damage(damage_dealer: Entity, damage_receiver: Entity, weapon: Weapon ):
|
|
||||||
var damage = weapon.get_damage() + damage_dealer.get_damage()
|
|
||||||
var armor = damage_receiver.get_armor()
|
|
||||||
var damage_percent = 90*( pow(MathUtils.e, 0.03*armor))
|
|
||||||
|
|
||||||
var damage_after_armor = damage * damage_percent
|
|
||||||
if damage_after_armor < 1 :
|
|
||||||
damage_after_armor = 1
|
|
||||||
|
|
||||||
var shield = damage_receiver.get_shield()
|
|
||||||
if shield > 0:
|
|
||||||
damage_receiver.reduce_shield(damage_after_armor)
|
|
||||||
else:
|
|
||||||
damage_receiver.reduce_health(damage_after_armor)
|
|
||||||
|
|
||||||
for effect in weapon.get_hit_effects():
|
|
||||||
effect.apply_effect(damage_dealer,damage_receiver)
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
extends Object
|
|
||||||
|
|
||||||
var e = 2.718281828459045235360287471352
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
extends Resource
|
|
||||||
class_name FlowFieldCell
|
|
||||||
|
|
||||||
var position:Vector3 = Vector3(0.0, 0.0, 0.0)
|
|
||||||
var flow_direction:Vector3 = Vector3(randf(), 0.0, randf())
|
|
||||||
|
|
||||||
func debug_process() -> void:
|
|
||||||
if flow_direction.length() > 0.0:
|
|
||||||
DebugDraw3D.draw_arrow(position, position + flow_direction, Color(1,1,1,1), 0.1)
|
|
||||||
else:
|
|
||||||
DebugDraw3D.draw_sphere(position, .05)
|
|
||||||
34
swarm_engine/flow_field_navigation/flow_field_compute.glsl
Normal file
34
swarm_engine/flow_field_navigation/flow_field_compute.glsl
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#[compute]
|
||||||
|
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
// Speicher für FlowField-Daten
|
||||||
|
layout(std430, set = 0, binding = 0) buffer FlowFieldBuffer {
|
||||||
|
vec2 flow_field[];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Zielposition und Grid-Daten
|
||||||
|
layout(push_constant) uniform Params {
|
||||||
|
vec2 target_pos;
|
||||||
|
float cell_size;
|
||||||
|
int grid_size_x;
|
||||||
|
int grid_size_z;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
uint x = gl_GlobalInvocationID.x;
|
||||||
|
uint z = gl_GlobalInvocationID.y;
|
||||||
|
|
||||||
|
if (x >= grid_size_x || z >= grid_size_z) return;
|
||||||
|
|
||||||
|
int index = int(z * grid_size_x + x);
|
||||||
|
|
||||||
|
// Zellzentrum berechnen
|
||||||
|
vec2 cell_center = vec2(x, z) * cell_size + vec2(cell_size * 0.5);
|
||||||
|
|
||||||
|
// Richtung zum Ziel berechnen
|
||||||
|
vec2 direction = normalize(target_pos - cell_center);
|
||||||
|
|
||||||
|
// Ergebnis in FlowField speichern
|
||||||
|
flow_field[index] = direction;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="glsl"
|
||||||
|
type="RDShaderFile"
|
||||||
|
uid="uid://bf4mkjohkqpox"
|
||||||
|
path="res://.godot/imported/flow_field_compute.glsl-51e5023d4249c63dbf26c3aa62523e13.res"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://swarm_engine/flow_field_navigation/flow_field_compute.glsl"
|
||||||
|
dest_files=["res://.godot/imported/flow_field_compute.glsl-51e5023d4249c63dbf26c3aa62523e13.res"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
@@ -1,71 +1,234 @@
|
|||||||
extends Node3D
|
extends Node3D
|
||||||
|
class_name FlowFieldNav
|
||||||
|
|
||||||
@export_group("Debug")
|
# https://docs.godotengine.org/cs/4.x/tutorials/shaders/compute_shaders.html#create-a-local-renderingdevice
|
||||||
@export var debugVisu: bool = true
|
# Das Updaten der flow richtung kann auf der grafikkarte gemacht werden mit compute shader
|
||||||
@export var line_color: Color = Color(1, 1, 1, 1)
|
|
||||||
|
|
||||||
@export_group("Grid")
|
@export_category("Debug Visualization")
|
||||||
@export var grid_size: int = 10
|
@export_group("Grid Center")
|
||||||
|
@export var show_grid_center: bool = false
|
||||||
|
@export_color_no_alpha var grid_center_color: Color = Color(1, 1, 1, 1)
|
||||||
|
@export var grid_center_size: float = 0.5
|
||||||
|
@export_group("Border")
|
||||||
|
@export var show_border: bool = false
|
||||||
|
@export_color_no_alpha var border_color: Color = Color(1, 1, 1, 1)
|
||||||
|
@export_group("Cells")
|
||||||
|
@export_subgroup("X Lines")
|
||||||
|
@export var show_x_lines: bool = false
|
||||||
|
@export_color_no_alpha var x_lines_color: Color = Color(1, 1, 1)
|
||||||
|
@export_subgroup("Z Lines")
|
||||||
|
@export var show_z_lines: bool = false
|
||||||
|
@export_color_no_alpha var z_lines_color: Color = Color(1, 1, 1)
|
||||||
|
@export_group("Arrows")
|
||||||
|
@export var show_arrows: bool = false
|
||||||
|
@export var arrows_size: float = 0.1
|
||||||
|
@export_color_no_alpha var cell_center_color: Color = Color(1, 1, 1)
|
||||||
|
@export var cell_center_size: float = 0.2
|
||||||
|
|
||||||
|
@export_category("Grid")
|
||||||
@export var cell_size: float = 1.0
|
@export var cell_size: float = 1.0
|
||||||
|
@export_group("Grid Size", "grid_size_")
|
||||||
|
@export var grid_size_x: int = 2
|
||||||
|
@export var grid_size_z: int = 5
|
||||||
|
|
||||||
var _cells: Dictionary
|
|
||||||
var grid_offset: Vector3
|
@export var target: Node3D = null
|
||||||
|
var flow_direction_list: Array[Vector2] = []
|
||||||
|
|
||||||
|
|
||||||
|
var half_size_x: float
|
||||||
|
var half_size_z: float
|
||||||
|
|
||||||
|
var rd: RenderingDevice
|
||||||
|
var shader: RID
|
||||||
|
var pipeline: RID
|
||||||
|
var flow_field_buffer: RID
|
||||||
|
var flow_field_data: PackedVector2Array
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
var half_size = (grid_size * cell_size) * 0.5
|
#var rendering_device := RenderingServer.create_local_rendering_device()
|
||||||
grid_offset = Vector3(-half_size + (cell_size * 0.5), 0, -half_size + (cell_size * 0.5))
|
#var shader_file := load("res://swarm_engine/flow_field_navigation/flow_field_compute.glsl")
|
||||||
create_grid()
|
#var shader_spirv: RDShaderSPIRV = shader_file.get_spirv()
|
||||||
|
#var shader_RID := rendering_device.shader_create_from_spirv(shader_spirv)
|
||||||
|
#
|
||||||
|
#var center_array: PackedVector3Array
|
||||||
|
#for x in range(grid_size_x):
|
||||||
|
#for z in range(grid_size_z):
|
||||||
|
#center_array.append(_get_cell_center_with_coordinates(x,z))
|
||||||
|
#
|
||||||
|
#var center_byte_array = center_array.to_byte_array()
|
||||||
|
#var storage_buffer_RID = rendering_device.storage_buffer_create(center_byte_array.size(), center_byte_array)
|
||||||
|
#
|
||||||
|
#var uniform := RDUniform.new()
|
||||||
|
#uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_STORAGE_BUFFER
|
||||||
|
#uniform.binding = 0
|
||||||
|
#uniform.add_id(storage_buffer_RID)
|
||||||
|
#var uniform_set_RID := rendering_device.uniform_set_create([uniform], shader_RID, 0)
|
||||||
|
#
|
||||||
|
#var pipeline_RID := rendering_device.compute_pipeline_create(shader_RID)
|
||||||
|
#var compute_list_id := rendering_device.compute_list_begin()
|
||||||
|
#
|
||||||
|
#rendering_device.compute_list_bind_compute_pipeline(compute_list_id, pipeline_RID)
|
||||||
|
#rendering_device.compute_list_bind_uniform_set(compute_list_id, uniform_set_RID, 0)
|
||||||
|
#rendering_device.compute_list_dispatch(compute_list_id, 1, 1, 1)
|
||||||
|
#rendering_device.compute_list_end()
|
||||||
|
#rendering_device.submit()
|
||||||
|
|
||||||
func create_grid() -> void:
|
#rd = RenderingServer.get_rendering_device()
|
||||||
_cells.clear()
|
#
|
||||||
for x in range(grid_size):
|
## Compute Shader laden
|
||||||
for z in range(grid_size):
|
#var shader_file = load("res://swarm_engine/flow_field_navigation/flow_field_compute.glsl")
|
||||||
var cell = FlowFieldCell.new()
|
#shader = rd.shader_create_from_spirv(shader_file.get_spirv())
|
||||||
var world_x = x * cell_size + grid_offset.x
|
#pipeline = rd.compute_pipeline_create(shader)
|
||||||
var world_z = z * cell_size + grid_offset.z
|
#
|
||||||
cell.position = Vector3(world_x, 0, world_z)
|
## Speicher für FlowField erstellen
|
||||||
_cells[Vector3(x, 0, z)] = cell # Dictionary mit Grid-Koordinaten als Key
|
#var buffer_size = grid_size_x * grid_size_z * 8 # Vector2 -> 2 floats = 8 Bytes pro Eintrag
|
||||||
|
#flow_field_buffer = rd.storage_buffer_create(buffer_size)
|
||||||
|
#flow_field_data.resize(grid_size_x * grid_size_z)
|
||||||
|
#
|
||||||
|
|
||||||
|
for x in range(grid_size_x):
|
||||||
|
for z in range(grid_size_z):
|
||||||
|
flow_direction_list.append(Vector2(0.0, 0.0))
|
||||||
|
half_size_x = (grid_size_x * cell_size) * 0.5
|
||||||
|
half_size_z = (grid_size_z * cell_size) * 0.5
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
if debugVisu:
|
|
||||||
_debug_draw_grid()
|
|
||||||
for cell in _cells.values():
|
|
||||||
cell.debug_process()
|
|
||||||
|
|
||||||
func _debug_draw_grid() -> void:
|
#_update_gpu_flow_field()
|
||||||
for x in range(grid_size + 1):
|
_update_flow_field()
|
||||||
var pos_x = x * cell_size + grid_offset.x - (cell_size * 0.5)
|
_draw_debug()
|
||||||
DebugDraw3D.draw_line(Vector3(pos_x, 0, grid_offset.z - (cell_size * 0.5)), Vector3(pos_x, 0, grid_offset.z + grid_size * cell_size - (cell_size * 0.5)), line_color)
|
|
||||||
|
|
||||||
for z in range(grid_size + 1):
|
func _update_gpu_flow_field():
|
||||||
var pos_z = z * cell_size + grid_offset.z - (cell_size * 0.5)
|
if not target:
|
||||||
DebugDraw3D.draw_line(Vector3(grid_offset.x - (cell_size * 0.5), 0, pos_z), Vector3(grid_offset.x + grid_size * cell_size - (cell_size * 0.5), 0, pos_z), line_color)
|
return
|
||||||
|
|
||||||
|
# Push-Constants für Shader setzen
|
||||||
|
var push_constants = PackedByteArray()
|
||||||
|
push_constants.append_array(PackedByteArray([
|
||||||
|
target.position.x,
|
||||||
|
target.position.z,
|
||||||
|
cell_size,
|
||||||
|
float(grid_size_x),
|
||||||
|
float(grid_size_z)
|
||||||
|
]))
|
||||||
|
|
||||||
|
# GPU Command erstellen
|
||||||
|
var compute_list = rd.compute_list_begin()
|
||||||
|
rd.compute_list_bind_compute_pipeline(compute_list, pipeline)
|
||||||
|
rd.compute_list_bind_storage_buffer(compute_list, flow_field_buffer, 0, 0)
|
||||||
|
rd.compute_list_set_push_constant(compute_list, push_constants, 0)
|
||||||
|
rd.compute_list_dispatch(compute_list, grid_size_x, grid_size_z, 1)
|
||||||
|
rd.compute_list_end()
|
||||||
|
|
||||||
|
# GPU Berechnung starten
|
||||||
|
rd.submit()
|
||||||
|
rd.sync()
|
||||||
|
|
||||||
|
# Daten von der GPU zurückholen
|
||||||
|
var buffer_data = rd.buffer_get_data(flow_field_buffer)
|
||||||
|
var output = buffer_data.to_float32_array()
|
||||||
|
|
||||||
|
# 2D-Array für FlowField initialisieren
|
||||||
|
flow_direction_list = []
|
||||||
|
for x in range(grid_size_x):
|
||||||
|
flow_direction_list.append([]) # Erstellt leere Arrays für jede X-Spalte
|
||||||
|
|
||||||
|
# Konvertiere die 1D-GPU-Daten in ein 2D-Array
|
||||||
|
for z in range(grid_size_z):
|
||||||
|
for x in range(grid_size_x):
|
||||||
|
var index = (z * grid_size_x + x) * 2 # 2 Floats pro Vector2
|
||||||
|
var flow_vector = Vector2(output[index], output[index + 1])
|
||||||
|
flow_direction_list[index] = flow_vector
|
||||||
|
|
||||||
|
func _update_flow_field():
|
||||||
|
if target != null:
|
||||||
|
for x in range(grid_size_x):
|
||||||
|
for z in range(grid_size_z):
|
||||||
|
var index = z * grid_size_x + x
|
||||||
|
var flow_direction = (target.position - _get_cell_center_with_coordinates(x,z)).normalized() * (cell_size/2)
|
||||||
|
flow_direction_list[index] = Vector2(flow_direction.x, flow_direction.z)
|
||||||
|
var target_index = _get_index_from_position(target.position)
|
||||||
|
flow_direction_list[target_index] = Vector2(0, 0)
|
||||||
|
|
||||||
|
|
||||||
# Gibt die Zelle basierend auf einer Weltposition zurück
|
func _draw_debug():
|
||||||
func get_cell_from_pos(world_pos: Vector3) -> FlowFieldCell:
|
if show_grid_center:
|
||||||
var grid_x = int((world_pos.x - grid_offset.x) / cell_size)
|
DebugDraw3D.draw_sphere(position, grid_center_size, grid_center_color)
|
||||||
var grid_z = int((world_pos.z - grid_offset.z) / cell_size)
|
if show_border:
|
||||||
var cell_pos = Vector3(grid_x, 0, grid_z)
|
_draw_border()
|
||||||
|
|
||||||
return _cells.get(cell_pos, null)
|
if show_x_lines:
|
||||||
|
_draw_x_lines()
|
||||||
|
|
||||||
|
if show_z_lines:
|
||||||
|
_draw_z_lines()
|
||||||
|
|
||||||
# Raycast zur Bestimmung der Zelle unter dem Mauszeiger
|
if show_arrows:
|
||||||
func _input(event):
|
_draw_arrows()
|
||||||
if event is InputEventMouseButton and event.pressed:
|
|
||||||
var camera = get_viewport().get_camera_3d()
|
|
||||||
var from = camera.project_ray_origin(get_viewport().get_mouse_position())
|
|
||||||
var to = from + camera.project_ray_normal(get_viewport().get_mouse_position()) * 1000
|
|
||||||
|
|
||||||
var space_state = get_world_3d().direct_space_state
|
func _draw_border():
|
||||||
var query = PhysicsRayQueryParameters3D.create(from, to)
|
var top_left = position - Vector3(half_size_x, 0 , half_size_z)
|
||||||
var result = space_state.intersect_ray(query)
|
var top_right = position + Vector3(half_size_x, 0, -half_size_z)
|
||||||
|
var bottom_left = position - Vector3(half_size_x, 0, -half_size_z)
|
||||||
|
var bottom_right = position + Vector3(half_size_x, 0, half_size_z)
|
||||||
|
|
||||||
if result.has("position"):
|
var lines: PackedVector3Array
|
||||||
var cell = get_cell_from_pos(result["position"])
|
lines.append_array(PackedVector3Array([top_left, top_right]))
|
||||||
if cell:
|
lines.append_array(PackedVector3Array([top_right, bottom_right]))
|
||||||
print("Zelle an", cell.position, ":", cell.flow_direction)
|
lines.append_array(PackedVector3Array([bottom_right, bottom_left]))
|
||||||
|
lines.append_array(PackedVector3Array([bottom_left, top_left]))
|
||||||
|
DebugDraw3D.draw_lines(lines, border_color)
|
||||||
|
|
||||||
|
func _draw_x_lines():
|
||||||
|
var lines: PackedVector3Array
|
||||||
|
for x in range(grid_size_x - 1):
|
||||||
|
var start = position - Vector3(half_size_x - ((x + 1) * cell_size), 0, half_size_z)
|
||||||
|
var end = position - Vector3(half_size_x - ((x + 1) * cell_size), 0, -half_size_z)
|
||||||
|
lines.append_array(PackedVector3Array([start, end]))
|
||||||
|
DebugDraw3D.draw_lines(lines, x_lines_color)
|
||||||
|
|
||||||
|
func _draw_z_lines():
|
||||||
|
var lines: PackedVector3Array
|
||||||
|
for z in range(grid_size_z - 1):
|
||||||
|
var start = position - Vector3(half_size_x, 0, half_size_z - ((z + 1) * cell_size))
|
||||||
|
var end = position - Vector3(-half_size_x, 0, half_size_z - ((z + 1) * cell_size))
|
||||||
|
lines.append_array(PackedVector3Array([start, end]))
|
||||||
|
DebugDraw3D.draw_lines(lines, z_lines_color)
|
||||||
|
|
||||||
|
func _draw_arrows():
|
||||||
|
var points: PackedVector3Array
|
||||||
|
for x in range(grid_size_x):
|
||||||
|
for z in range(grid_size_z):
|
||||||
|
var cell_center = _get_cell_center_with_coordinates(x,z)
|
||||||
|
var index = z * grid_size_x + x
|
||||||
|
if flow_direction_list[index].length() > 0.0:
|
||||||
|
var direction = Vector3(flow_direction_list[index].x, 0, flow_direction_list[index].y).normalized()
|
||||||
|
var arrow_end = cell_center + direction * (cell_size * 0.4)
|
||||||
|
DebugDraw3D.draw_arrow(cell_center, arrow_end, ColorHelper.get_direction_color(direction), arrows_size)
|
||||||
else:
|
else:
|
||||||
print("Keine Zelle gefunden!")
|
points.append(cell_center)
|
||||||
|
DebugDraw3D.draw_points(points, DebugDraw3D.POINT_TYPE_SQUARE, cell_center_size, cell_center_color)
|
||||||
|
|
||||||
|
func _get_cell_center_with_coordinates(x:int, z:int) -> Vector3:
|
||||||
|
return position + Vector3(
|
||||||
|
(-half_size_x + (x * cell_size) + (cell_size * 0.5)),
|
||||||
|
0,
|
||||||
|
(-half_size_z + (z * cell_size) + (cell_size * 0.5)))
|
||||||
|
|
||||||
|
func _get_coordinates_from_position(pos: Vector3) -> Vector2i:
|
||||||
|
return Vector2i(int((pos.x - position.x + half_size_x) / cell_size),
|
||||||
|
int((pos.z - position.z + half_size_z) / cell_size))
|
||||||
|
|
||||||
|
func _get_index_from_position(pos: Vector3) -> int:
|
||||||
|
var pos_coord = _get_coordinates_from_position(pos)
|
||||||
|
if _is_coordinate_valid(pos_coord):
|
||||||
|
return -1
|
||||||
|
return pos_coord.y * grid_size_x + pos_coord.x
|
||||||
|
|
||||||
|
func _is_coordinate_valid(coord: Vector2i) -> bool:
|
||||||
|
return coord.x < 0 or coord.x >= grid_size_x or coord.y < 0 or coord.y >= grid_size_z
|
||||||
|
|
||||||
|
func get_direction_from_position(position: Vector3) -> Vector3:
|
||||||
|
var index = _get_index_from_position(position)
|
||||||
|
return Vector3(flow_direction_list[index].x, 0, flow_direction_list[index].y)
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
extends Node3D
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
DebugDraw2D.set_text("Frames drawn", Engine.get_frames_drawn())
|
|
||||||
DebugDraw2D.set_text("FPS", Engine.get_frames_per_second())
|
|
||||||
DebugDraw2D.set_text("delta", delta)
|
|
||||||
@@ -1,20 +1,71 @@
|
|||||||
[gd_scene load_steps=3 format=3 uid="uid://bwo12me8h21q5"]
|
[gd_scene load_steps=6 format=3 uid="uid://bwo12me8h21q5"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://swarm_engine/swarm_engine_debug_level.gd" id="1_f0ttr"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cn2xvs2g7box5" path="res://swarm_engine/flow_field_navigation/flow_field_navigation.tscn" id="1_xwcpn"]
|
[ext_resource type="PackedScene" uid="uid://cn2xvs2g7box5" path="res://swarm_engine/flow_field_navigation/flow_field_navigation.tscn" id="1_xwcpn"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cdau7qryen3uq" path="res://swarm_engine/swarm_unit/swarm_unit.tscn" id="3_6kohq"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dycbdcrwsm6wu" path="res://experimente/felox/player.tscn" id="6_wayso"]
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_3dwe5"]
|
||||||
|
size = Vector2(400, 400)
|
||||||
|
|
||||||
|
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_vtddf"]
|
||||||
|
points = PackedVector3Array(-200, 0, -200, -200, 0, 200, 200, 0, -200, 200, 0, 200)
|
||||||
|
|
||||||
[node name="World" type="Node3D"]
|
[node name="World" type="Node3D"]
|
||||||
script = ExtResource("1_f0ttr")
|
|
||||||
|
|
||||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
|
transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0)
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
|
|
||||||
[node name="FlowFieldNavigation" parent="." instance=ExtResource("1_xwcpn")]
|
[node name="FlowFieldNavigation" parent="." node_paths=PackedStringArray("target") instance=ExtResource("1_xwcpn")]
|
||||||
grid_size = 100
|
unique_name_in_owner = true
|
||||||
cell_size = 2.0
|
show_grid_center = true
|
||||||
|
grid_center_color = Color(0, 0.0833333, 1, 1)
|
||||||
|
show_border = true
|
||||||
|
show_x_lines = true
|
||||||
|
x_lines_color = Color(1, 0.45, 0, 1)
|
||||||
|
show_z_lines = true
|
||||||
|
z_lines_color = Color(1, 0, 0.0166664, 1)
|
||||||
|
show_arrows = true
|
||||||
|
cell_center_color = Color(0.702375, 0.0507974, 0.96251, 1)
|
||||||
|
cell_size = 4.0
|
||||||
|
grid_size_x = 50
|
||||||
|
grid_size_z = 50
|
||||||
|
target = NodePath("../player")
|
||||||
|
|
||||||
[node name="CSGSphere3D" type="CSGSphere3D" parent="FlowFieldNavigation"]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = SubResource("PlaneMesh_3dwe5")
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="."]
|
[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 0.331371, 0.943501, 0, -0.943501, 0.331371, 0, 13.203, 5.65752)
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D"]
|
||||||
|
shape = SubResource("ConvexPolygonShape3D_vtddf")
|
||||||
|
|
||||||
|
[node name="player" parent="." instance=ExtResource("6_wayso")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3.50529)
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="player"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 10, 8)
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D" parent="."]
|
||||||
|
|
||||||
|
[node name="SwarmUnit" parent="Node3D" node_paths=PackedStringArray("flow_field_navigation") instance=ExtResource("3_6kohq")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0338392, 0, -41.7085)
|
||||||
|
move_speed = 4
|
||||||
|
flow_field_navigation = NodePath("../../FlowFieldNavigation")
|
||||||
|
|
||||||
|
[node name="SwarmUnit2" parent="Node3D" node_paths=PackedStringArray("flow_field_navigation") instance=ExtResource("3_6kohq")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -17.4426, 0, -41.7085)
|
||||||
|
move_speed = 4
|
||||||
|
flow_field_navigation = NodePath("../../FlowFieldNavigation")
|
||||||
|
|
||||||
|
[node name="SwarmUnit3" parent="Node3D" node_paths=PackedStringArray("flow_field_navigation") instance=ExtResource("3_6kohq")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0338392, 0, -58.7671)
|
||||||
|
move_speed = 4
|
||||||
|
flow_field_navigation = NodePath("../../FlowFieldNavigation")
|
||||||
|
|
||||||
|
[node name="SwarmUnit4" parent="Node3D" node_paths=PackedStringArray("flow_field_navigation") instance=ExtResource("3_6kohq")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -17.4426, 0, -58.7671)
|
||||||
|
move_speed = 4
|
||||||
|
flow_field_navigation = NodePath("../../FlowFieldNavigation")
|
||||||
|
|||||||
36
swarm_engine/swarm_unit/multi_mesh_instance_3d.gd
Normal file
36
swarm_engine/swarm_unit/multi_mesh_instance_3d.gd
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
extends MultiMeshInstance3D
|
||||||
|
|
||||||
|
@export var move_speed = 2
|
||||||
|
@export var number: int = 100
|
||||||
|
@export var stretch: int = 2
|
||||||
|
|
||||||
|
|
||||||
|
@onready var flow_field_navigation: FlowFieldNav = %FlowFieldNavigation
|
||||||
|
@onready var player: Player = %player
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
for x in range(number):
|
||||||
|
for z in range(number):
|
||||||
|
var index = z * number + x
|
||||||
|
self.multimesh.set_instance_transform(index, Transform3D(Basis(), Vector3(x * stretch, 0.0, -z * stretch)))
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
for x in range(number):
|
||||||
|
for z in range(number):
|
||||||
|
var index = z * number + x
|
||||||
|
var current_trans = self.multimesh.get_instance_transform(index)
|
||||||
|
|
||||||
|
var cell = flow_field_navigation.get_cell_from_pos(current_trans.origin)
|
||||||
|
if cell != null and cell.flow_direction.length() > 0.0:
|
||||||
|
var movement = cell.flow_direction.normalized() * move_speed * delta
|
||||||
|
current_trans.origin += movement
|
||||||
|
|
||||||
|
var direction_to_player = (player.position - current_trans.origin).normalized()
|
||||||
|
var target_rotation_y = Quaternion(Vector3.UP, atan2(-direction_to_player.x, -direction_to_player.z))
|
||||||
|
var fix_rotation_x = Quaternion(Vector3.RIGHT, deg_to_rad(-90))
|
||||||
|
var fix_rotation_y_180 = Quaternion(Vector3.UP, deg_to_rad(180))
|
||||||
|
var final_rotation = fix_rotation_y_180 * target_rotation_y * fix_rotation_x
|
||||||
|
current_trans.basis = Basis(final_rotation)
|
||||||
|
|
||||||
|
self.multimesh.set_instance_transform(index, current_trans)
|
||||||
10
swarm_engine/swarm_unit/swarm_unit.gd
Normal file
10
swarm_engine/swarm_unit/swarm_unit.gd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
extends CharacterBody3D
|
||||||
|
|
||||||
|
@export var move_speed = 2
|
||||||
|
@export var flow_field_navigation: FlowFieldNav
|
||||||
|
|
||||||
|
func _physics_process(delta: float) -> void:
|
||||||
|
var flow_direction = flow_field_navigation.get_direction_from_position(position)
|
||||||
|
if flow_direction.length() > 0.0:
|
||||||
|
var movement = flow_direction.normalized() * move_speed * delta
|
||||||
|
position += movement
|
||||||
11
swarm_engine/swarm_unit/swarm_unit.tscn
Normal file
11
swarm_engine/swarm_unit/swarm_unit.tscn
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://cdau7qryen3uq"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://swarm_engine/swarm_unit/swarm_unit.gd" id="1_eynce"]
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_o8sb1"]
|
||||||
|
|
||||||
|
[node name="SwarmUnit" type="CharacterBody3D"]
|
||||||
|
script = ExtResource("1_eynce")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
|
shape = SubResource("CapsuleShape3D_o8sb1")
|
||||||
Reference in New Issue
Block a user