From b3dcaabe07ec5330e9d3b3f64c35fe8164ae1e6f Mon Sep 17 00:00:00 2001 From: Minimata Date: Wed, 21 Jan 2026 12:32:58 +0100 Subject: [PATCH] basic targeting system --- global.json | 7 +++ maps/GYMs/enemies.tscn | 2 + player_controller/PlayerController.tscn | 31 ++++++++++++- player_controller/PlayerUi.cs | 24 +++++++++- player_controller/Scripts/PlayerController.cs | 44 +++++++++++++++++-- project.godot | 4 ++ systems/dash/DashSystem.cs | 9 ++-- systems/head/HeadSystem.cs | 8 ++++ 8 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 global.json diff --git a/global.json b/global.json new file mode 100644 index 00000000..f4fd3857 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "9.0.0", + "rollForward": "latestMajor", + "allowPrerelease": true + } +} \ No newline at end of file diff --git a/maps/GYMs/enemies.tscn b/maps/GYMs/enemies.tscn index 9b26b9ec..521bb0ab 100644 --- a/maps/GYMs/enemies.tscn +++ b/maps/GYMs/enemies.tscn @@ -47,10 +47,12 @@ metadata/_custom_type_script = "uid://b4cwruitopcee" [sub_resource type="Resource" id="Resource_5fa36"] script = ExtResource("6_ybosk") +GravityModifier = 1.0 metadata/_custom_type_script = "uid://dtpxijlnb2c5" [sub_resource type="Resource" id="Resource_blhrq"] script = ExtResource("6_ybosk") +GravityModifier = 1.0 metadata/_custom_type_script = "uid://dtpxijlnb2c5" [sub_resource type="Resource" id="Resource_1hrkh"] diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index 9289a15b..1fe62036 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=56 format=3 uid="uid://bei4nhkf8lwdo"] +[gd_scene load_steps=58 format=3 uid="uid://bei4nhkf8lwdo"] [ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"] [ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"] @@ -47,6 +47,7 @@ [ext_resource type="Texture2D" uid="uid://bnwj7ltdfximr" path="res://icon.svg" id="30_h23go"] [ext_resource type="Texture2D" uid="uid://chvt6g0xn5c2m" path="res://systems/dash/light-ring.jpg" id="32_lgpc8"] [ext_resource type="Script" uid="uid://b4dwolbvt8our" path="res://addons/godot_state_charts/history_state.gd" id="41_ruloh"] +[ext_resource type="Texture2D" uid="uid://buu21kg4kkhiw" path="res://guide_examples/shared/fireball/fireball.svg" id="42_cmijs"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"] height = 1.7 @@ -57,6 +58,9 @@ radius = 0.45 [sub_resource type="SphereShape3D" id="SphereShape3D_q14ux"] radius = 1.0 +[sub_resource type="SphereShape3D" id="SphereShape3D_cmijs"] +radius = 1.0 + [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nodcl"] transparency = 1 albedo_color = Color(0, 0.627451, 0.6313726, 0.49019608) @@ -202,6 +206,13 @@ monitorable = false transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -1.5) shape = SubResource("SphereShape3D_q14ux") +[node name="CloseEnemyDetector" type="ShapeCast3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) +shape = SubResource("SphereShape3D_cmijs") +target_position = Vector3(0, 0, -5) +collision_mask = 16 + [node name="StairsSystem" type="Node3D" parent="."] script = ExtResource("7_bmt5a") @@ -344,7 +355,6 @@ enabled = false initial_node_to_watch = NodePath("../StateChart") [node name="UI" type="Control" parent="."] -visible = false layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -434,6 +444,23 @@ unique_name_in_owner = true custom_minimum_size = Vector2(100, 10) layout_mode = 2 +[node name="EnemyTarget" type="TextureRect" parent="UI"] +unique_name_in_owner = true +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -20.0 +offset_right = 20.0 +offset_bottom = 20.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("42_cmijs") +expand_mode = 1 + [node name="StateChart" type="Node" parent="."] script = ExtResource("25_wv70j") metadata/_custom_type_script = "uid://couw105c3bde4" diff --git a/player_controller/PlayerUi.cs b/player_controller/PlayerUi.cs index 743b575a..23b87e3a 100644 --- a/player_controller/PlayerUi.cs +++ b/player_controller/PlayerUi.cs @@ -4,16 +4,36 @@ using System; public partial class PlayerUi : Control { private TextureRect[] _dashIcons = new TextureRect[3]; + private TextureRect _enemyTarget; + + public enum TargetState + { + NoTarget, + TargetTooFar, + TargetInRange, + } + + public record TargetProperties(TargetState State, Vector2 Position); public override void _Ready() { - base._Ready(); - _dashIcons[0] = GetNode("%Dash1"); _dashIcons[1] = GetNode("%Dash2"); _dashIcons[2] = GetNode("%Dash3"); + + _enemyTarget = GetNode("%EnemyTarget"); } + public void SetEnemyTargetProperties(TargetProperties targetProperties) + { + var (state, position) = targetProperties; + + var visible = state != TargetState.NoTarget; + _enemyTarget.SetVisible(visible); + _enemyTarget.SetPosition(position); + } + + public void SetNumberOfDashesLeft(int numberOfDashes) { int index = 1; diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index c181b9bc..19f24627 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -341,6 +341,9 @@ public partial class PlayerController : CharacterBody3D, private bool _canAttack = true; private readonly List _hitEnemies = new List(); + private ShapeCast3D _closeEnemyDetector; + private Camera3D _camera; + public override void _Ready() { LoadSettings(); @@ -351,6 +354,8 @@ public partial class PlayerController : CharacterBody3D, // General use stuff PlayerUi = GetNode("UI"); + _closeEnemyDetector = GetNode("%CloseEnemyDetector"); + // DashIndicator = GetNode("%DashIndicator"); PowerCooldownIndicator = GetNode("%DashCooldownIndicator"); PowerCooldownIndicator.Visible = false; @@ -366,7 +371,7 @@ public partial class PlayerController : CharacterBody3D, // Camera stuff HeadSystem = GetNode("HeadSystem"); - Camera3D camera = GetNode("HeadSystem/CameraSmooth/Camera3D"); + _camera = GetNode("HeadSystem/CameraSmooth/Camera3D"); Node3D cameraSmooth = GetNode("HeadSystem/CameraSmooth"); // Movement stuff @@ -479,8 +484,8 @@ public partial class PlayerController : CharacterBody3D, _gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity"); MantleSystem.Init(); StairsSystem.Init(stairsBelowRayCast3D, stairsAheadRayCast3D, cameraSmooth); - DashSystem.Init(HeadSystem, camera); - WeaponSystem.Init(HeadSystem, camera); + DashSystem.Init(HeadSystem, _camera); + WeaponSystem.Init(HeadSystem, _camera); WallHugSystem.Init(); EmpoweredActionsLeft = MaxNumberOfEmpoweredActions; @@ -1789,11 +1794,20 @@ public partial class PlayerController : CharacterBody3D, { if (_currentInputBufferFrames > 0) _currentInputBufferFrames -= 1; + // Manage head and camera movement LookAround(delta); + + // Manage general movement Velocity += ComputeKnockback(); MoveSlideAndHandleStairs((float) delta); - MantleSystem.ProcessMantle(_grounded.Active); + // Manage gameplay systems + MantleSystem.ProcessMantle(_grounded.Active); + HandleEnemyTargeting(); + + if (_closeEnemyDetector.IsColliding()) + + // Manage dash target and tutorial specific stuff if (WeaponSystem.InHandState.Active && !_aiming.Active && TutorialDone) { DashIndicatorMesh.Visible = false; @@ -1806,6 +1820,28 @@ public partial class PlayerController : CharacterBody3D, DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition); } } + public void HandleEnemyTargeting() + { + _closeEnemyDetector.SetRotation(HeadSystem.GetGlobalLookRotation()); + + var enemyTargetState = PlayerUi.TargetState.NoTarget; + var positionOnScreen = Vector2.Zero; + if (!_closeEnemyDetector.IsColliding()) + { + PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); + return; + } + var collidedObject = _closeEnemyDetector.GetCollider(0); + if (collidedObject is not Node3D target) + { + PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); + return; + } + + enemyTargetState = PlayerUi.TargetState.TargetInRange; + positionOnScreen = _camera.UnprojectPosition(target.GlobalPosition); + PlayerUi.SetEnemyTargetProperties(new PlayerUi.TargetProperties(enemyTargetState, positionOnScreen)); + } /////////////////////////// // Hit Management /////// diff --git a/project.godot b/project.godot index 113e849f..f6026e96 100644 --- a/project.godot +++ b/project.godot @@ -37,6 +37,10 @@ window/size/viewport_height=1080 project/assembly_name="Movement tests" +[editor] + +movie_writer/movie_file="D:/Godot/Projects/movement-tests/communication/movie.avi" + [editor_plugins] enabled=PackedStringArray("res://addons/godot_state_charts/plugin.cfg", "res://addons/guide/plugin.cfg", "res://addons/maaacks_game_template/plugin.cfg", "res://addons/shaker/plugin.cfg") diff --git a/systems/dash/DashSystem.cs b/systems/dash/DashSystem.cs index bb2a8f40..67ab70c0 100644 --- a/systems/dash/DashSystem.cs +++ b/systems/dash/DashSystem.cs @@ -22,7 +22,7 @@ public partial class DashSystem: Node3D public Vector3 PlannedMantleLocation { get; set; } public MantleSystem MantleSystem { get; set; } - private Node3D _head; + private HeadSystem _head; private ShapeCast3D _dashCast3D; private Camera3D _camera; private Vector3 _dashDirection = Vector3.Zero; @@ -49,7 +49,7 @@ public partial class DashSystem: Node3D public float DashCastRadius { get; set; } - public void Init(Node3D head, Camera3D camera) + public void Init(HeadSystem head, Camera3D camera) { _dashCast3D = GetNode("DashCast3D"); var dashShape = _dashCast3D.GetShape() as SphereShape3D; @@ -93,10 +93,7 @@ public partial class DashSystem: Node3D public void PrepareDash() { - _dashCast3D.SetRotation(new Vector3( - _camera.Rotation.X, - _head.Rotation.Y, - _camera.Rotation.Z)); + _dashCast3D.SetRotation(_head.GetGlobalLookRotation()); (HasHit, PlannedLocation, CollisionPoint, CollisionNormal) = ComputeDashLocation(); diff --git a/systems/head/HeadSystem.cs b/systems/head/HeadSystem.cs index 5a87dd9a..608896d8 100644 --- a/systems/head/HeadSystem.cs +++ b/systems/head/HeadSystem.cs @@ -310,6 +310,14 @@ public partial class HeadSystem : Node3D return GetGlobalTransform().Basis.Z; } + public Vector3 GetGlobalLookRotation() + { + return new Vector3( + _camera.Rotation.X, + Rotation.Y, + _camera.Rotation.Z); + } + public void SetHeight(float height) { Position = new Vector3(Position.X, height, Position.Z);