From 431c174dc70deed54190070eb8a9e5e83e527eca Mon Sep 17 00:00:00 2001 From: niefia <99533148+niefia@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:16:58 +0100 Subject: [PATCH 1/4] Damage rework - Hit position & Direction Reworked the damage system to include Hit position & direction Added options to instantiate scenes at either global or local hit position Added option to apply force to Rigidbodies on hits Added option to spawn decal on any hitscan collision WIP - Still need to sort melee weapons position --- .../cogito/CogitoObjects/cogito_projectile.gd | 13 +++++--- addons/cogito/Components/HitboxComponent.gd | 31 ++++++++++++++++++- addons/cogito/Components/HitboxComponent.tscn | 2 ++ .../DemoScenes/COGITO_4_Laboratory.tscn | 4 +-- addons/cogito/Enemies/cogito_basic_enemy.tscn | 6 ++-- .../Pickups/pickup_laser_rifle.tscn | 5 +-- .../PackedScenes/projectile_pistol.tscn | 4 +-- addons/cogito/Wieldables/laser_rifle.tscn | 3 +- .../Wieldables/wieldable_laser_rifle.gd | 16 ++++++++-- addons/cogito/Wieldables/wieldable_pickaxe.gd | 6 ++-- 10 files changed, 68 insertions(+), 22 deletions(-) diff --git a/addons/cogito/CogitoObjects/cogito_projectile.gd b/addons/cogito/CogitoObjects/cogito_projectile.gd index c67f9a0c..8a2c0bf8 100644 --- a/addons/cogito/CogitoObjects/cogito_projectile.gd +++ b/addons/cogito/CogitoObjects/cogito_projectile.gd @@ -31,6 +31,9 @@ func on_timeout(): ## Checking collision event for property tags. func _on_body_entered(collider: Node): + var collision_point = global_transform.origin + var bullet_direction = (collision_point - CogitoSceneManager._current_player_node.get_global_transform().origin).normalized() ##This is hacky TODO needs to be fixed for Multiplayer support + if stick_on_impact: self.linear_velocity = Vector3.ZERO self.angular_velocity = Vector3.ZERO @@ -39,12 +42,12 @@ func _on_body_entered(collider: Node): if collider.has_signal("damage_received"): if( !collider.cogito_properties && !cogito_properties): # Case where neither projectile nor the object hit have properties defined. print("Projectile: Collider nor projectile have CogitoProperties, damaging as usual.") - deal_damage(collider) + deal_damage(collider,bullet_direction, collision_point) return if( collider.cogito_properties && !cogito_properties): # Case were only collider has properties. print("Projectile: Collider has CogitoProperties, currently ignoring these and damaging as usual.") - deal_damage(collider) + deal_damage(collider,bullet_direction, collision_point) if( !collider.cogito_properties && cogito_properties): # Case where only the projectile has properties defined. match cogito_properties.material_properties: @@ -59,7 +62,7 @@ func _on_body_entered(collider: Node): if( cogito_properties.material_properties == CogitoProperties.MaterialProperties.SOFT && collider.cogito_properties.material_properties == CogitoProperties.MaterialProperties.SOFT): # When both objects are soft, damage the hit object. print("Projectile: Soft object hit, dealing damage.") - deal_damage(collider) + deal_damage(collider,bullet_direction, collision_point) # Manually setting the reaction collider and calling reactions on object hit, skipping the reaction threshold time. collider.cogito_properties.reaction_collider = self @@ -84,9 +87,9 @@ func stick_to_object(collider: Node): #self.linear_velocity = Vector3.ZERO #self.angular_velocity = Vector3.ZERO -func deal_damage(collider: Node): +func deal_damage(collider: Node,bullet_direction,bullet_position): print(self.name, ": dealing damage amount ", damage_amount, " on collider ", collider.name) - collider.damage_received.emit(damage_amount) + collider.damage_received.emit(damage_amount,bullet_direction,bullet_position) if destroy_on_impact: die() diff --git a/addons/cogito/Components/HitboxComponent.gd b/addons/cogito/Components/HitboxComponent.gd index dfbb602a..d79bc560 100644 --- a/addons/cogito/Components/HitboxComponent.gd +++ b/addons/cogito/Components/HitboxComponent.gd @@ -2,6 +2,16 @@ extends Node class_name HitboxComponent @export var health_attribute : CogitoHealthAttribute +## PackedScene that will get spawned on global hit position +@export var spawn_at_global_collision: PackedScene +## PackedScene that will get spawned on parents local hit position +@export var spawn_at_local_collision: PackedScene +## Apply force to Rigidbodies on hit +@export var apply_force_on_hit : bool +## Multiplier of force applied to rigidbody, if force apply is true +@export var applied_force_multipler : int + +@onready var parent = get_parent() func _ready() -> void: if get_parent().has_signal("damage_received"): @@ -10,6 +20,25 @@ func _ready() -> void: else: print("HitboxComponent: Parent ", get_parent().name, " is missing a damage_received() signal.") -func damage(damage_amount:float): + +func damage(damage_amount: float, _hit_direction:= Vector3.ZERO, _hit_position:= Vector3.ZERO): + if health_attribute: health_attribute.subtract(damage_amount) + + if spawn_at_global_collision != null: + var spawned_object = spawn_at_global_collision.instantiate() + spawned_object.position = _hit_position + get_tree().current_scene.add_child(spawned_object) + + if spawn_at_local_collision != null: + var local_hit_position = parent.to_local(_hit_position) + var spawned_object = spawn_at_local_collision.instantiate() + spawned_object.position = local_hit_position + parent.add_child(spawned_object) + + if apply_force_on_hit: + ##TODO Handle CharacterBody3D for NPC knockback + if parent is RigidBody3D: + parent.apply_impulse(_hit_direction * damage_amount * applied_force_multipler, _hit_position) + diff --git a/addons/cogito/Components/HitboxComponent.tscn b/addons/cogito/Components/HitboxComponent.tscn index 11431f0a..c180aa6d 100644 --- a/addons/cogito/Components/HitboxComponent.tscn +++ b/addons/cogito/Components/HitboxComponent.tscn @@ -4,3 +4,5 @@ [node name="HitboxComponent" type="Node"] script = ExtResource("1_7oy1x") +apply_force_on_hit = true +applied_force_multipler = 10 diff --git a/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn b/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn index f5d73e67..dac6ca58 100644 --- a/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn +++ b/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn @@ -84,7 +84,7 @@ volumetric_fog_ambient_inject = 0.1 volumetric_fog_sky_affect = 0.1 volumetric_fog_temporal_reprojection_amount = 0.85 -[sub_resource type="Resource" id="Resource_n6ij1"] +[sub_resource type="Resource" id="Resource_6vnub"] resource_local_to_scene = true script = ExtResource("4_hlewe") grid = true @@ -897,7 +897,7 @@ environment = SubResource("Environment_obnk3") [node name="Player" parent="." instance=ExtResource("2_7qwrr")] transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5.13854, 0.8, -5.43073) -inventory_data = SubResource("Resource_n6ij1") +inventory_data = SubResource("Resource_6vnub") [node name="CONNECTOR_TO_LOBBY" type="Node3D" parent="."] diff --git a/addons/cogito/Enemies/cogito_basic_enemy.tscn b/addons/cogito/Enemies/cogito_basic_enemy.tscn index e5af46d5..b1b9130d 100644 --- a/addons/cogito/Enemies/cogito_basic_enemy.tscn +++ b/addons/cogito/Enemies/cogito_basic_enemy.tscn @@ -6,9 +6,9 @@ [ext_resource type="AudioStream" uid="uid://bd7xfxmsaeu0o" path="res://addons/cogito/Assets/Audio/435666__mirkosukovic__alarm-siren.wav" id="3_7u8yw"] [ext_resource type="PackedScene" uid="uid://cqgg1nng0vvbh" path="res://addons/cogito/Components/Attributes/HealthAttribute.tscn" id="4_y8n8v"] [ext_resource type="PackedScene" uid="uid://bc2hryr610vgo" path="res://addons/cogito/PackedScenes/simple_particle_puff.tscn" id="5_ni6ul"] -[ext_resource type="Script" path="res://addons/cogito/Components/HitboxComponent.gd" id="5_qh1ls"] [ext_resource type="PackedScene" uid="uid://crv3r7dscbxlx" path="res://addons/cogito/Enemies/body/basic_enemy_corpse.tscn" id="7_8vdb4"] [ext_resource type="PackedScene" uid="uid://cj0yaeh3yg7tu" path="res://addons/cogito/Components/Properties/CogitoProperties.tscn" id="7_15n6t"] +[ext_resource type="PackedScene" uid="uid://k28yrbg3k3pw" path="res://addons/cogito/Components/HitboxComponent.tscn" id="8_lq5js"] [ext_resource type="AudioStream" uid="uid://up2hfhgq1qx6" path="res://addons/cogito/Assets/Audio/Kenney/Footsteps/footstep00.ogg" id="8_vyi83"] [ext_resource type="AudioStream" uid="uid://crj07wq4oocwi" path="res://addons/cogito/Assets/Audio/Kenney/Footsteps/footstep01.ogg" id="9_5fsuu"] [ext_resource type="AudioStream" uid="uid://dewyukd562k37" path="res://addons/cogito/Assets/Audio/Kenney/Footsteps/footstep02.ogg" id="10_ab7fy"] @@ -86,7 +86,6 @@ script = ExtResource("2_6jysp") detection_ray_cast_3d = NodePath("DetectionRayCast3D") indicator_light = NodePath("../Mesh_Body/Mesh_Face/IndicatorLight") detection_area = NodePath("DetectionArea3D") -spot_time = 2.0 alarm_sound = ExtResource("3_7u8yw") indicator_mesh = NodePath("../Mesh_Body/Mesh_Face") @@ -116,8 +115,7 @@ spawn_on_death = Array[PackedScene]([ExtResource("5_ni6ul"), ExtResource("7_8vdb value_max = 5.0 value_start = 5.0 -[node name="HitboxComponent" type="Node" parent="." node_paths=PackedStringArray("health_attribute")] -script = ExtResource("5_qh1ls") +[node name="HitboxComponent" parent="." node_paths=PackedStringArray("health_attribute") instance=ExtResource("8_lq5js")] health_attribute = NodePath("../HealthAttribute") [node name="CogitoProperties" parent="." instance=ExtResource("7_15n6t")] diff --git a/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn b/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn index ff714584..d474ba33 100644 --- a/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn +++ b/addons/cogito/PackedScenes/Pickups/pickup_laser_rifle.tscn @@ -135,11 +135,12 @@ size = Vector3(0.0973389, 0.0952759, 0.815624) [sub_resource type="BoxShape3D" id="BoxShape3D_5bhcv"] size = Vector3(0.0973389, 0.0457916, 0.443713) -[sub_resource type="Resource" id="Resource_4kc11"] +[sub_resource type="Resource" id="Resource_fmssf"] resource_local_to_scene = true script = ExtResource("3_iw0du") inventory_item = ExtResource("3_auoh1") quantity = 1 +origin_index = -1 [node name="Pickup_LaserRifle" type="RigidBody3D"] collision_layer = 3 @@ -166,4 +167,4 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00152874, 0.187482, 0.03864 shape = SubResource("BoxShape3D_5bhcv") [node name="PickupComponent" parent="." instance=ExtResource("2_3uch0")] -slot_data = SubResource("Resource_4kc11") +slot_data = SubResource("Resource_fmssf") diff --git a/addons/cogito/PackedScenes/projectile_pistol.tscn b/addons/cogito/PackedScenes/projectile_pistol.tscn index 0df335e9..2ed8fe3c 100644 --- a/addons/cogito/PackedScenes/projectile_pistol.tscn +++ b/addons/cogito/PackedScenes/projectile_pistol.tscn @@ -23,7 +23,7 @@ rings = 1 height = 0.25 radius = 0.05 -[sub_resource type="Resource" id="Resource_s1k6p"] +[sub_resource type="Resource" id="Resource_1m67k"] resource_local_to_scene = true script = ExtResource("4_tbkmk") inventory_item = ExtResource("3_7etap") @@ -62,7 +62,7 @@ wait_time = 30.0 autostart = true [node name="PickupComponent" parent="." instance=ExtResource("4_acy7b")] -slot_data = SubResource("Resource_s1k6p") +slot_data = SubResource("Resource_1m67k") [node name="CogitoProperties" parent="." instance=ExtResource("5_6jfy1")] material_properties = 1 diff --git a/addons/cogito/Wieldables/laser_rifle.tscn b/addons/cogito/Wieldables/laser_rifle.tscn index 5e6f506a..5fc17af8 100644 --- a/addons/cogito/Wieldables/laser_rifle.tscn +++ b/addons/cogito/Wieldables/laser_rifle.tscn @@ -2,8 +2,8 @@ [ext_resource type="Script" path="res://addons/cogito/Wieldables/wieldable_laser_rifle.gd" id="1_2rut3"] [ext_resource type="AudioStream" uid="uid://clsajk36s7luk" path="res://addons/cogito/Assets/Audio/Kenney/error_004.ogg" id="2_f7ale"] -[ext_resource type="Resource" uid="uid://txiu5yxexevm" path="res://addons/cogito/InventoryPD/Items/Cogito_LaserRifle.tres" id="2_i0fx0"] [ext_resource type="PackedScene" uid="uid://dnauxhdncgngx" path="res://addons/cogito/PackedScenes/laser_ray.tscn" id="2_ic084"] +[ext_resource type="PackedScene" uid="uid://bc2hryr610vgo" path="res://addons/cogito/PackedScenes/simple_particle_puff.tscn" id="3_aueyu"] [ext_resource type="AnimationLibrary" uid="uid://c1du0rcgmr542" path="res://addons/cogito/Wieldables/Animations/Wieldable_LaserRifle.res" id="3_fjq23"] [ext_resource type="Script" path="res://addons/cogito/Assets/Shader/ViewmodelSpace.gd" id="5_fa3wp"] @@ -269,6 +269,7 @@ script = ExtResource("1_2rut3") laser_ray_prefab = ExtResource("2_ic084") ray_lifespan = 3.0 default_position = Vector3(0.329, -0.264, -0.535) +collision_decal = ExtResource("3_aueyu") sound_primary_use = ExtResource("2_f7ale") wieldable_mesh = NodePath("LaserRifleMesh") anim_equip = "LaserRifle/equip" diff --git a/addons/cogito/Wieldables/wieldable_laser_rifle.gd b/addons/cogito/Wieldables/wieldable_laser_rifle.gd index d547bb68..7e182727 100644 --- a/addons/cogito/Wieldables/wieldable_laser_rifle.gd +++ b/addons/cogito/Wieldables/wieldable_laser_rifle.gd @@ -13,6 +13,8 @@ extends CogitoWieldable @export var ads_fov = 65 ## Default position for tweening from ADS @export var default_position : Vector3 +## Scene that spawns when a bullet of the weapon collides with anything +@export var collision_decal : PackedScene @export_group("Audio") @export var sound_primary_use : AudioStream @@ -103,12 +105,20 @@ func hit_scan_collision(collision_point:Vector3): spawn_node.add_child(instantiated_ray) if bullet_collision: - hit_scan_damage(bullet_collision.collider) + hit_scan_damage(bullet_collision.collider, bullet_direction, bullet_collision.position) + hit_scan_decal(bullet_collision) -func hit_scan_damage(collider): +func hit_scan_damage(collider, bullet_direction, bullet_position): if collider.has_signal("damage_received"): - collider.damage_received.emit(item_reference.wieldable_damage) + collider.damage_received.emit(item_reference.wieldable_damage,bullet_direction,bullet_position) + + +func hit_scan_decal(bullet_collision): + var hit_indicator = collision_decal.instantiate() + var world = get_tree().get_root().get_child(0) + world.add_child(hit_indicator) + hit_indicator.global_translate(bullet_collision.position) # Function called when wieldable reload is attempted diff --git a/addons/cogito/Wieldables/wieldable_pickaxe.gd b/addons/cogito/Wieldables/wieldable_pickaxe.gd index bf54edeb..7fe293dc 100644 --- a/addons/cogito/Wieldables/wieldable_pickaxe.gd +++ b/addons/cogito/Wieldables/wieldable_pickaxe.gd @@ -16,7 +16,7 @@ func _ready(): wieldable_mesh.hide() damage_area.body_entered.connect(_on_body_entered) - + if uses_stamina: player_stamina = grab_player_stamina_attribute() @@ -53,4 +53,6 @@ func action_primary(_passed_item_reference:InventoryItemPD, _is_released: bool): func _on_body_entered(collider): if collider.has_signal("damage_received"): - collider.damage_received.emit(item_reference.wieldable_damage) + var hit_position = collider.global_transform.origin + var bullet_direction = (collider.global_transform.origin - CogitoSceneManager._current_player_node.get_global_transform().origin).normalized() ##This is hacky TODO needs to be fixed for Multiplayer support + collider.damage_received.emit(item_reference.wieldable_damage,bullet_direction,hit_position) From 38182b246116c30554a74c2757c89157b7cc9c4d Mon Sep 17 00:00:00 2001 From: niefia <99533148+niefia@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:11:36 +0100 Subject: [PATCH 2/4] Replaced player refs, fixed button damage interaction Removed direct player references for better multiplayer support in future Fixed button damage interaction Also fixed a typo in the readme --- Readme.md | 2 +- addons/cogito/CogitoObjects/cogito_button.gd | 2 +- addons/cogito/CogitoObjects/cogito_projectile.gd | 6 +++++- addons/cogito/CogitoObjects/cogito_switch.gd | 2 +- addons/cogito/PackedScenes/projectile_pistol.tscn | 4 ++-- addons/cogito/Wieldables/wieldable_pickaxe.gd | 3 ++- addons/cogito/Wieldables/wieldable_toy_pistol.gd | 1 + 7 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Readme.md b/Readme.md index e7d9d724..35f5a1aa 100644 --- a/Readme.md +++ b/Readme.md @@ -13,7 +13,7 @@ COGITO is made by [Philip Drobar](https://www.philipdrobar.com) with help from [ ## Principles of this template The structure of this template always tries to adhere to the following principles: - **Complete**: When you download COGITO and press play, you get a functioning project out of the box. Game menu, save slot select, options and a playable level are all included. -- **Versatile**: Wether your game is set in the future, the past or the present, use melee, projectile or no weapons at all, have low poly, stylized or realistic graphics, the template will have features for you. +- **Versatile**: Whether your game is set in the future, the past or the present, use melee, projectile or no weapons at all, have low poly, stylized or realistic graphics, the template will have features for you. - **Modular**: Do not want to use a feature? You will be able to hide it, ignore it or strip it out without breaking COGITO. At the same time, COGITO is designed to be extendable with your own custom features or other add-ons. - **Approachable**: While there will always be a learning curve, we strive to make COGTIO approachable and intuitive to use, so it doesn't get in your way of making your game. diff --git a/addons/cogito/CogitoObjects/cogito_button.gd b/addons/cogito/CogitoObjects/cogito_button.gd index b1a4112e..a7a5c6cc 100644 --- a/addons/cogito/CogitoObjects/cogito_button.gd +++ b/addons/cogito/CogitoObjects/cogito_button.gd @@ -104,7 +104,7 @@ func press(): object.interact(player_interaction_component) -func _on_damage_received(damage): +func _on_damage_received(_damage,_bullet_direction,_bullet_position): interact(CogitoSceneManager._current_player_node.player_interaction_component) diff --git a/addons/cogito/CogitoObjects/cogito_projectile.gd b/addons/cogito/CogitoObjects/cogito_projectile.gd index 8a2c0bf8..f87dd8e5 100644 --- a/addons/cogito/CogitoObjects/cogito_projectile.gd +++ b/addons/cogito/CogitoObjects/cogito_projectile.gd @@ -16,6 +16,8 @@ var damage_amount : int = 0 ## Array of Scenes that will get spawned on parent position on death. @export var spawn_on_death : Array[PackedScene] = [] +var Direction + func _ready(): add_to_group("interactable") self.add_to_group("Persist") #Adding object to group for persistence @@ -88,7 +90,9 @@ func stick_to_object(collider: Node): #self.angular_velocity = Vector3.ZERO func deal_damage(collider: Node,bullet_direction,bullet_position): - print(self.name, ": dealing damage amount ", damage_amount, " on collider ", collider.name) + bullet_direction = Direction + print(self.name, ": dealing damage amount ", damage_amount, " on collider ", collider.name, " at ",bullet_position, " in direction ", Direction ) + collider.damage_received.emit(damage_amount,bullet_direction,bullet_position) if destroy_on_impact: die() diff --git a/addons/cogito/CogitoObjects/cogito_switch.gd b/addons/cogito/CogitoObjects/cogito_switch.gd index 9e3305f3..78c2eb51 100644 --- a/addons/cogito/CogitoObjects/cogito_switch.gd +++ b/addons/cogito/CogitoObjects/cogito_switch.gd @@ -129,7 +129,7 @@ func check_for_item() -> bool: player_interaction_component.send_hint(null,item_hint) # Sends the key hint with the default hint icon. return false -func _on_damage_received(): +func _on_damage_received(_damage,_bullet_direction,_bullet_position): interact(CogitoSceneManager._current_player_node.player_interaction_component) func set_state(): diff --git a/addons/cogito/PackedScenes/projectile_pistol.tscn b/addons/cogito/PackedScenes/projectile_pistol.tscn index 2ed8fe3c..3e1e8f53 100644 --- a/addons/cogito/PackedScenes/projectile_pistol.tscn +++ b/addons/cogito/PackedScenes/projectile_pistol.tscn @@ -23,7 +23,7 @@ rings = 1 height = 0.25 radius = 0.05 -[sub_resource type="Resource" id="Resource_1m67k"] +[sub_resource type="Resource" id="Resource_rrf3o"] resource_local_to_scene = true script = ExtResource("4_tbkmk") inventory_item = ExtResource("3_7etap") @@ -62,7 +62,7 @@ wait_time = 30.0 autostart = true [node name="PickupComponent" parent="." instance=ExtResource("4_acy7b")] -slot_data = SubResource("Resource_1m67k") +slot_data = SubResource("Resource_rrf3o") [node name="CogitoProperties" parent="." instance=ExtResource("5_6jfy1")] material_properties = 1 diff --git a/addons/cogito/Wieldables/wieldable_pickaxe.gd b/addons/cogito/Wieldables/wieldable_pickaxe.gd index 7fe293dc..be41ddac 100644 --- a/addons/cogito/Wieldables/wieldable_pickaxe.gd +++ b/addons/cogito/Wieldables/wieldable_pickaxe.gd @@ -54,5 +54,6 @@ func action_primary(_passed_item_reference:InventoryItemPD, _is_released: bool): func _on_body_entered(collider): if collider.has_signal("damage_received"): var hit_position = collider.global_transform.origin - var bullet_direction = (collider.global_transform.origin - CogitoSceneManager._current_player_node.get_global_transform().origin).normalized() ##This is hacky TODO needs to be fixed for Multiplayer support + var player = player_interaction_component.get_parent() + var bullet_direction = (collider.global_transform.origin - player.get_global_transform().origin).normalized() collider.damage_received.emit(item_reference.wieldable_damage,bullet_direction,hit_position) diff --git a/addons/cogito/Wieldables/wieldable_toy_pistol.gd b/addons/cogito/Wieldables/wieldable_toy_pistol.gd index ccff3030..905903a9 100644 --- a/addons/cogito/Wieldables/wieldable_toy_pistol.gd +++ b/addons/cogito/Wieldables/wieldable_toy_pistol.gd @@ -69,6 +69,7 @@ func action_primary(_passed_item_reference : InventoryItemPD, _is_released: bool Projectile.global_transform.basis = bullet_point.global_transform.basis Projectile.damage_amount = _passed_item_reference.wieldable_damage Projectile.set_linear_velocity(Direction * projectile_velocity) + Projectile.Direction = Direction Projectile.reparent(get_tree().get_current_scene()) From a52400cb9dba505f126dfdbfe52305513f17e31c Mon Sep 17 00:00:00 2001 From: niefia <99533148+niefia@users.noreply.github.com> Date: Thu, 17 Oct 2024 10:28:13 +0100 Subject: [PATCH 3/4] Used camera collision for melee hit position --- addons/cogito/Components/HitboxComponent.tscn | 2 +- addons/cogito/Wieldables/wieldable_pickaxe.gd | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/addons/cogito/Components/HitboxComponent.tscn b/addons/cogito/Components/HitboxComponent.tscn index c180aa6d..e26b429a 100644 --- a/addons/cogito/Components/HitboxComponent.tscn +++ b/addons/cogito/Components/HitboxComponent.tscn @@ -5,4 +5,4 @@ [node name="HitboxComponent" type="Node"] script = ExtResource("1_7oy1x") apply_force_on_hit = true -applied_force_multipler = 10 +applied_force_multipler = 2 diff --git a/addons/cogito/Wieldables/wieldable_pickaxe.gd b/addons/cogito/Wieldables/wieldable_pickaxe.gd index be41ddac..d2433ec9 100644 --- a/addons/cogito/Wieldables/wieldable_pickaxe.gd +++ b/addons/cogito/Wieldables/wieldable_pickaxe.gd @@ -11,6 +11,7 @@ extends CogitoWieldable var trigger_has_been_pressed : bool = false var player_stamina : CogitoAttribute = null + func _ready(): if wieldable_mesh: wieldable_mesh.hide() @@ -19,6 +20,7 @@ func _ready(): if uses_stamina: player_stamina = grab_player_stamina_attribute() + func grab_player_stamina_attribute() -> CogitoAttribute: @@ -53,7 +55,8 @@ func action_primary(_passed_item_reference:InventoryItemPD, _is_released: bool): func _on_body_entered(collider): if collider.has_signal("damage_received"): - var hit_position = collider.global_transform.origin var player = player_interaction_component.get_parent() - var bullet_direction = (collider.global_transform.origin - player.get_global_transform().origin).normalized() - collider.damage_received.emit(item_reference.wieldable_damage,bullet_direction,hit_position) + var hit_position = player_interaction_component.Get_Camera_Collision() + var bullet_direction = (hit_position - player.get_global_transform().origin).normalized() + collider.damage_received.emit(item_reference.wieldable_damage, bullet_direction, hit_position) + From 1b4809ad23a1830af731a0f0c4fbd8272d0dcd9b Mon Sep 17 00:00:00 2001 From: niefia <99533148+niefia@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:34:31 +0100 Subject: [PATCH 4/4] Hitbox-Collider melee collision & NPC knockback Added option of Hitbox-Collider melee collision, seems from my testing to be more accurate since it uses the actual hitbox, but less reliable so have it as an option. Added knockback to the NPC so they can respond to damage --- addons/cogito/Components/HitboxComponent.gd | 2 ++ .../DemoScenes/COGITO_4_Laboratory.tscn | 4 ++-- addons/cogito/Enemies/cogito_basic_enemy.gd | 19 ++++++++++++++- addons/cogito/Enemies/cogito_basic_enemy.tscn | 1 - .../PackedScenes/projectile_pistol.tscn | 4 ++-- addons/cogito/Wieldables/wieldable_pickaxe.gd | 23 +++++++++++++++++-- 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/addons/cogito/Components/HitboxComponent.gd b/addons/cogito/Components/HitboxComponent.gd index d79bc560..57fd8683 100644 --- a/addons/cogito/Components/HitboxComponent.gd +++ b/addons/cogito/Components/HitboxComponent.gd @@ -41,4 +41,6 @@ func damage(damage_amount: float, _hit_direction:= Vector3.ZERO, _hit_position:= ##TODO Handle CharacterBody3D for NPC knockback if parent is RigidBody3D: parent.apply_impulse(_hit_direction * damage_amount * applied_force_multipler, _hit_position) + if parent is CharacterBody3D: + parent.apply_knockback(_hit_direction *damage_amount * applied_force_multipler) diff --git a/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn b/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn index dac6ca58..b901087a 100644 --- a/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn +++ b/addons/cogito/DemoScenes/COGITO_4_Laboratory.tscn @@ -84,7 +84,7 @@ volumetric_fog_ambient_inject = 0.1 volumetric_fog_sky_affect = 0.1 volumetric_fog_temporal_reprojection_amount = 0.85 -[sub_resource type="Resource" id="Resource_6vnub"] +[sub_resource type="Resource" id="Resource_uka7b"] resource_local_to_scene = true script = ExtResource("4_hlewe") grid = true @@ -897,7 +897,7 @@ environment = SubResource("Environment_obnk3") [node name="Player" parent="." instance=ExtResource("2_7qwrr")] transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 5.13854, 0.8, -5.43073) -inventory_data = SubResource("Resource_6vnub") +inventory_data = SubResource("Resource_uka7b") [node name="CONNECTOR_TO_LOBBY" type="Node3D" parent="."] diff --git a/addons/cogito/Enemies/cogito_basic_enemy.gd b/addons/cogito/Enemies/cogito_basic_enemy.gd index 42909ba3..17596453 100644 --- a/addons/cogito/Enemies/cogito_basic_enemy.gd +++ b/addons/cogito/Enemies/cogito_basic_enemy.gd @@ -81,6 +81,16 @@ var can_play_footstep: bool = true var wiggle_vector : Vector2 = Vector2.ZERO var wiggle_index : float = 0.0 +var knockback_force: Vector3 = Vector3.ZERO +var knockback_timer: float = 0.0 +@export var knockback_duration: float = 0.5 +@export var knockback_strength: float = 10.0 + + +func apply_knockback(direction: Vector3): + knockback_force = direction.normalized() * knockback_strength + knockback_timer = knockback_duration + func _enter_tree() -> void: current_state = EnemyState.IDLE @@ -102,7 +112,14 @@ func find_cogito_properties(): func _physics_process(delta: float) -> void: if attack_cooldown > 0: attack_cooldown -= delta - + + if knockback_timer > 0: + knockback_timer -= delta + velocity = knockback_force + knockback_force = lerp(knockback_force, Vector3.ZERO, delta * 5) + move_and_slide() + return + match current_state: EnemyState.PATROLLING: handle_patrolling(delta) diff --git a/addons/cogito/Enemies/cogito_basic_enemy.tscn b/addons/cogito/Enemies/cogito_basic_enemy.tscn index b1b9130d..0e278cc7 100644 --- a/addons/cogito/Enemies/cogito_basic_enemy.tscn +++ b/addons/cogito/Enemies/cogito_basic_enemy.tscn @@ -55,7 +55,6 @@ stream_4/stream = ExtResource("12_3m7c4") stream_4/weight = 1.0 [node name="CogitoEnemy" type="CharacterBody3D"] -motion_mode = 1 script = ExtResource("1_0lcvu") attack_stagger = 20.0 attack_sound = ExtResource("2_q5685") diff --git a/addons/cogito/PackedScenes/projectile_pistol.tscn b/addons/cogito/PackedScenes/projectile_pistol.tscn index 3e1e8f53..bd97d63b 100644 --- a/addons/cogito/PackedScenes/projectile_pistol.tscn +++ b/addons/cogito/PackedScenes/projectile_pistol.tscn @@ -23,7 +23,7 @@ rings = 1 height = 0.25 radius = 0.05 -[sub_resource type="Resource" id="Resource_rrf3o"] +[sub_resource type="Resource" id="Resource_w3sph"] resource_local_to_scene = true script = ExtResource("4_tbkmk") inventory_item = ExtResource("3_7etap") @@ -62,7 +62,7 @@ wait_time = 30.0 autostart = true [node name="PickupComponent" parent="." instance=ExtResource("4_acy7b")] -slot_data = SubResource("Resource_rrf3o") +slot_data = SubResource("Resource_w3sph") [node name="CogitoProperties" parent="." instance=ExtResource("5_6jfy1")] material_properties = 1 diff --git a/addons/cogito/Wieldables/wieldable_pickaxe.gd b/addons/cogito/Wieldables/wieldable_pickaxe.gd index d2433ec9..ef1a847b 100644 --- a/addons/cogito/Wieldables/wieldable_pickaxe.gd +++ b/addons/cogito/Wieldables/wieldable_pickaxe.gd @@ -4,6 +4,8 @@ extends CogitoWieldable @export var damage_area : Area3D @export var uses_stamina : bool = false @export var stamina_cost : int = 4 +##Collision hit can be defined using Camera-Collider raycast, or Hitbox-Collider raycast. Camera-Collider is more reliable but less accurate, Hitbox-collider is more accurate but less reliable +@export var use_camera_collision : bool @export_group("Audio") @export var swing_sound : AudioStream @@ -56,7 +58,24 @@ func action_primary(_passed_item_reference:InventoryItemPD, _is_released: bool): func _on_body_entered(collider): if collider.has_signal("damage_received"): var player = player_interaction_component.get_parent() - var hit_position = player_interaction_component.Get_Camera_Collision() - var bullet_direction = (hit_position - player.get_global_transform().origin).normalized() + var hit_position : Vector3 + var bullet_direction : Vector3 + + if use_camera_collision: + #Camera-Collider raycast + hit_position = player_interaction_component.Get_Camera_Collision() + bullet_direction = (hit_position - player.get_global_transform().origin).normalized() + else: + #Hitbox-Collider raycast + var space_state = damage_area.get_world_3d().direct_space_state + var hitbox_origin = damage_area.global_transform.origin + var ray_params = PhysicsRayQueryParameters3D.new() + ray_params.from = hitbox_origin + ray_params.to = collider.global_transform.origin + var result = space_state.intersect_ray(ray_params) + if result.size() > 0: + hit_position = result.position + bullet_direction = (hit_position - hitbox_origin).normalized() + collider.damage_received.emit(item_reference.wieldable_damage, bullet_direction, hit_position)