From d59635a6ddae16a36f72bd8a8eb74c84fd58632b Mon Sep 17 00:00:00 2001 From: Ryan Reed Date: Mon, 24 Mar 2025 11:13:39 -0400 Subject: [PATCH] Add ability to throw a block --- autoloads/entity_manager.gd | 2 +- scenes/blocks/dropped_block.gd | 63 +++++++++++++++----- scenes/blocks/dropped_block.gd.uid | 2 +- scenes/blocks/dropped_block.tscn | 93 ++++++++++++++++++------------ scenes/world/world.gd | 4 +- 5 files changed, 111 insertions(+), 53 deletions(-) diff --git a/autoloads/entity_manager.gd b/autoloads/entity_manager.gd index df62167..5d2a46a 100644 --- a/autoloads/entity_manager.gd +++ b/autoloads/entity_manager.gd @@ -1,6 +1,6 @@ extends Node signal create_block(id: String, position: Vector3) -signal drop_block(id: String, position: Vector3) +signal drop_block(id: String, start_position: Vector3, direction: Vector3, velocity: float) signal reset_world ## Used for signaling a deletion of all in the BlocksContainer and DroppedItemsContainer signal spawn_player(transform: Transform3D) diff --git a/scenes/blocks/dropped_block.gd b/scenes/blocks/dropped_block.gd index 29ecfc4..71266e3 100644 --- a/scenes/blocks/dropped_block.gd +++ b/scenes/blocks/dropped_block.gd @@ -1,22 +1,59 @@ class_name DroppedBlock -extends Node3D +extends RigidBody3D -# TODO: It may not make sense to use Block here due to the use of StaticBody -# StaticBody shouldn't generally be moved, making throwing and even the animation not recommended -@export var block_scale: float = .25 +## The amount of time to wait before PickupArea is set to monitorable[br] +## This is to ensure that the item isn't picked up immediately after throwing +@export var pickup_timeout: int = 1 +@export var animation_player: AnimationPlayer +@export var block_mesh: MeshInstance3D +@export var pickup_area: Area3D -@onready var animation_player: AnimationPlayer = $AnimationPlayer -@onready var block: Block = $Block +var id: String +var resource: BlockResource +var impulse: Vector3 = Vector3.ZERO -func initialize(id: String, _position: Vector3) -> void: - _position.y -= .2 # Bring the block closer to the floor (Probably a better way to handle this) - position = _position - block.set_id(id) - block.collision_shape.disabled = true - block.scale = Vector3(block_scale, block_scale, block_scale) +func _ready() -> void: animation_player.play("start_animation") + await get_tree().create_timer(pickup_timeout).timeout # Give block enough time to clear player collision + pickup_area.monitoring = true + + +# TODO: Rename to something else (maybe remove()) +# Move to signal? +func destroy_block() -> void: + queue_free() + +func get_id() -> String: + return id + +func initialize(block_id: String, start_position: Vector3, drop_direction: Vector3 = Vector3.ZERO, drop_impulse: float = 0.0) -> void: + set_id(block_id) + position = start_position + impulse = drop_direction * drop_impulse + apply_central_impulse(impulse) + +func set_id(block_id: String) -> void: + id = block_id + _load_resource_data() + _apply_material() + + +func _apply_material() -> void: + if block_mesh == null: return + if resource == null: return + block_mesh.set_surface_override_material(0, resource.material_texture) + +func _load_resource_data() -> void: + if not id: + printerr("Could not load resource data. Block ID was empty.") + return + + if not id in DBItems.data: + printerr("Could not load resource data. Unknown Block ID: ", id) + return + resource = DBItems.data[id] func _on_pickup_area_body_entered(body: Node3D) -> void: @@ -24,7 +61,7 @@ func _on_pickup_area_body_entered(body: Node3D) -> void: # TODO: Update stack count dynamically var stack_count: int = 1 - var item: DBItemResource = (DBItems.data[block.get_id()] as Resource).duplicate() + var item: DBItemResource = (DBItems.data[get_id()] as Resource).duplicate() item.amount = stack_count InventoryManager.item_picked_up.emit(item) queue_free() diff --git a/scenes/blocks/dropped_block.gd.uid b/scenes/blocks/dropped_block.gd.uid index 64c9fa3..0a3af08 100644 --- a/scenes/blocks/dropped_block.gd.uid +++ b/scenes/blocks/dropped_block.gd.uid @@ -1 +1 @@ -uid://dkd2qbndc3q1o +uid://d2uws50yjvp6w diff --git a/scenes/blocks/dropped_block.tscn b/scenes/blocks/dropped_block.tscn index ad99a30..01beab1 100644 --- a/scenes/blocks/dropped_block.tscn +++ b/scenes/blocks/dropped_block.tscn @@ -1,35 +1,45 @@ -[gd_scene load_steps=13 format=3 uid="uid://bn2olldntd7a6"] +[gd_scene load_steps=10 format=3 uid="uid://dq6alec7d35gc"] -[ext_resource type="Script" uid="uid://dkd2qbndc3q1o" path="res://scenes/blocks/dropped_block.gd" id="1_50ggx"] -[ext_resource type="Script" uid="uid://buvqmrrtmxs2h" path="res://scenes/blocks/block.gd" id="2_qtifl"] -[ext_resource type="Material" uid="uid://bgc6efqf8aiqo" path="res://assets/materials/block_highlight.tres" id="3_8xfh1"] -[ext_resource type="Texture2D" uid="uid://dsvk3faenewrl" path="res://assets/textures/grass-block.png" id="3_ix4xk"] +[ext_resource type="Script" uid="uid://d2uws50yjvp6w" path="res://scenes/blocks/dropped_block.gd" id="1_y8usf"] +[ext_resource type="Texture2D" uid="uid://dsvk3faenewrl" path="res://assets/textures/grass-block.png" id="4_jhjal"] [sub_resource type="Animation" id="Animation_kym7p"] length = 0.001 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("Block:position") +tracks/0/path = NodePath("BlockMesh:position") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [Vector3(0, 0, 0)] +"values": [Vector3(0, -0.2, 0)] } tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("Block:rotation") +tracks/1/path = NodePath("BlockMesh:rotation") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 0, -"values": [Vector3(0, 0, 0)] +"values": [Vector3(0, 0, 0.261799)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("BlockMesh:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0.25, 0.25, 0.25)] } [sub_resource type="Animation" id="Animation_50ggx"] @@ -40,26 +50,38 @@ step = 0.1 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("Block:position") +tracks/0/path = NodePath("BlockMesh:position") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.5, 1, 1.5, 2), "transitions": PackedFloat32Array(1, 1, 1, 1, 1), "update": 0, -"values": [Vector3(0, 0, 0), Vector3(0, 0.1, 0), Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)] +"values": [Vector3(0, -0.2, 0), Vector3(0, -0.3, 0), Vector3(0, -0.2, 0), Vector3(0, -0.1, 0), Vector3(0, -0.2, 0)] } tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("Block:rotation") +tracks/1/path = NodePath("BlockMesh:rotation") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { -"times": PackedFloat32Array(0, 1, 2), -"transitions": PackedFloat32Array(1, 1, 1), +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(1, 1), "update": 0, -"values": [Vector3(0, 0, 0.261799), Vector3(0, 3.14159, 0.261799), Vector3(0, 6.28319, 0.261799)] +"values": [Vector3(0, 0, 0.261799), Vector3(0, 6.28319, 0.261799)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("BlockMesh:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0.25, 0.25, 0.25)] } [sub_resource type="AnimationLibrary" id="AnimationLibrary_kym7p"] @@ -68,50 +90,49 @@ _data = { &"start_animation": SubResource("Animation_50ggx") } -[sub_resource type="BoxShape3D" id="BoxShape3D_n5naa"] - -[sub_resource type="BoxMesh" id="BoxMesh_7fut1"] -material = ExtResource("3_8xfh1") -size = Vector3(1.01, 1.01, 1.01) +[sub_resource type="BoxShape3D" id="BoxShape3D_kkyxx"] [sub_resource type="BoxMesh" id="BoxMesh_e15ke"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4e127"] -albedo_texture = ExtResource("3_ix4xk") +albedo_texture = ExtResource("4_jhjal") texture_filter = 0 [sub_resource type="SphereShape3D" id="SphereShape3D_5kft2"] radius = 1.0 -[node name="DroppedBlock" type="Node3D"] -script = ExtResource("1_50ggx") +[node name="DroppedBlock" type="RigidBody3D" node_paths=PackedStringArray("animation_player", "block_mesh", "pickup_area")] +collision_layer = 4 +script = ExtResource("1_y8usf") +animation_player = NodePath("AnimationPlayer") +block_mesh = NodePath("BlockMesh") +pickup_area = NodePath("PickupArea") [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { &"": SubResource("AnimationLibrary_kym7p") } -autoplay = "start_animation" +autoplay = "RESET" -[node name="Block" type="StaticBody3D" parent="."] -script = ExtResource("2_qtifl") - -[node name="CollisionShape3D" type="CollisionShape3D" parent="Block"] -shape = SubResource("BoxShape3D_n5naa") - -[node name="HighlightMesh" type="MeshInstance3D" parent="Block"] +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] visible = false -mesh = SubResource("BoxMesh_7fut1") +shape = SubResource("BoxShape3D_kkyxx") -[node name="BlockMesh" type="MeshInstance3D" parent="Block"] +[node name="BlockMesh" type="MeshInstance3D" parent="."] +transform = Transform3D(0.241481, -0.0647047, 0, 0.0647047, 0.241481, 0, 0, 0, 0.25, 0, -0.2, 0) mesh = SubResource("BoxMesh_e15ke") +skeleton = NodePath("") surface_material_override/0 = SubResource("StandardMaterial3D_4e127") -[node name="PickupArea" type="Area3D" parent="Block"] +[node name="PickupArea" type="Area3D" parent="."] transform = Transform3D(0.965926, -0.258819, 0, 0.258819, 0.965926, 0, 0, 0, 1, 0, 0, 0) +visible = false collision_layer = 4 collision_mask = 2 +monitoring = false +monitorable = false -[node name="CollisionShape3D" type="CollisionShape3D" parent="Block/PickupArea"] +[node name="CollisionShape3D" type="CollisionShape3D" parent="PickupArea"] shape = SubResource("SphereShape3D_5kft2") -[connection signal="body_entered" from="Block/PickupArea" to="." method="_on_pickup_area_body_entered"] +[connection signal="body_entered" from="PickupArea" to="." method="_on_pickup_area_body_entered"] diff --git a/scenes/world/world.gd b/scenes/world/world.gd index edbd476..7b2ebc9 100644 --- a/scenes/world/world.gd +++ b/scenes/world/world.gd @@ -32,10 +32,10 @@ func _create_block(id: String, block_position: Vector3) -> void: blocks_container.add_child(block) -func _create_dropped_block(id: String, block_position: Vector3) -> void: +func _create_dropped_block(id: String, start_position: Vector3, direction: Vector3 = Vector3.ZERO, velocity: float = 0.0) -> void: var block: DroppedBlock = Globals.DROPPED_BLOCK_PREFAB.instantiate() dropped_items_container.add_child(block) - block.initialize(id, block_position) + block.initialize(id, start_position, direction, velocity) func _create_test_blocks() -> void: var test_blocks: Array = ["001", "002", "003", "004", "005", "006"]