Compare commits

...

8 Commits

Author SHA1 Message Date
8d1e7ebb4f some jumping animations
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 18s
Create tag and build when new code gets to main / Export (push) Successful in 10m30s
2026-01-20 13:23:42 +01:00
a257306999 reorganizing stuff
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 10m45s
2026-01-20 12:23:26 +01:00
2e5fcb6a75 implemented player health, knockback, invicibility frames and hitstop
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Export (push) Successful in 9m56s
2026-01-20 12:05:31 +01:00
87a9fad005 now that's an animation
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Export (push) Successful in 9m57s
2026-01-19 23:15:40 +01:00
837b3d7705 hyperfocused on the procedural FP animations
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 19s
Create tag and build when new code gets to main / Export (push) Successful in 9m46s
2026-01-19 18:51:27 +01:00
4224333963 improved weapon system and cleaner weapon setup
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Export (push) Successful in 10m20s
2026-01-19 17:25:12 +01:00
4dd48bed70 orienting flying sword 2026-01-19 16:55:22 +01:00
abe6f42a3b some juice work on the first person weapon 2026-01-19 16:46:00 +01:00
20 changed files with 893 additions and 167 deletions

View File

@@ -0,0 +1,13 @@
[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://buevqo8w8fq75"]
[ext_resource type="Texture2D" uid="uid://qtu5ue4ixkwm" path="res://assets/swords/fbx/Texture_MAp_sword.png" id="1_ke6g8"]
[resource]
resource_name = "Sword_mat_map"
vertex_color_use_as_albedo = true
albedo_texture = ExtResource("1_ke6g8")
emission_enabled = true
use_z_clip_scale = true
z_clip_scale = 0.5
use_fov_override = true
fov_override = 30.0

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -20,7 +20,6 @@ public partial class CHealth : Node, IHealthable
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
{
GD.Print(CurrentHealth);
CurrentHealth -= damageRecord.Damage.DamageDealt;
HealthChanged?.Invoke(this, CurrentHealth);

View File

@@ -1,27 +1,29 @@
[gd_scene load_steps=54 format=3 uid="uid://bei4nhkf8lwdo"]
[gd_scene load_steps=55 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"]
[ext_resource type="Resource" uid="uid://bl5crtu1gkrtr" path="res://systems/inputs/base_mode/base_mode.tres" id="3_cresl"]
[ext_resource type="Script" uid="uid://b0u23nkpaimyc" path="res://components/damage/CDamageable.cs" id="4_q7bng"]
[ext_resource type="PackedScene" uid="uid://c4ikbhojckpnc" path="res://components/health/CHealth.tscn" id="3_q7bng"]
[ext_resource type="Resource" uid="uid://bjyd801wvverk" path="res://player_controller/resources/player_health.tres" id="4_m8gvy"]
[ext_resource type="Resource" uid="uid://cpdaw41ah5gic" path="res://systems/inputs/base_mode/rotate_y.tres" id="4_rxwoh"]
[ext_resource type="Resource" uid="uid://ccrb5xsnphc8" path="res://systems/inputs/base_mode/rotate_floorplane.tres" id="5_4u7i3"]
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://components/damage/RDamageModifier.cs" id="5_q7bng"]
[ext_resource type="PackedScene" uid="uid://hpsg4fqwrx1u" path="res://components/damage/CDamageable.tscn" id="5_jb43f"]
[ext_resource type="Resource" uid="uid://f3vs6l4m623s" path="res://systems/inputs/base_mode/move_left.tres" id="5_q14ux"]
[ext_resource type="Resource" uid="uid://dyru7mxo121w6" path="res://player_controller/resources/player_normal_damage_mod.tres" id="6_cmijs"]
[ext_resource type="Resource" uid="uid://t612lts1wi1s" path="res://systems/inputs/base_mode/move_right.tres" id="6_q7bng"]
[ext_resource type="Script" uid="uid://cwbvxlfvmocc1" path="res://player_controller/Scripts/StairsSystem.cs" id="7_bmt5a"]
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://systems/inputs/base_mode/move_front.tres" id="7_m8gvy"]
[ext_resource type="PackedScene" uid="uid://bctpe34ddamg5" path="res://components/knockback/CKnockback.tscn" id="7_x835q"]
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://systems/inputs/base_mode/move_back.tres" id="8_jb43f"]
[ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://systems/inputs/base_mode/aim_release.tres" id="8_lhb11"]
[ext_resource type="Resource" uid="uid://bs8b0oojixm4q" path="res://player_controller/resources/player_knockback.tres" id="8_m8gvy"]
[ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://systems/inputs/base_mode/aim_down.tres" id="8_obsfv"]
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="8_qu4wy"]
[ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="9_nob5r"]
[ext_resource type="Resource" uid="uid://bdit2jy5gbpts" path="res://systems/inputs/base_mode/jump.tres" id="10_4u7i3"]
[ext_resource type="Script" uid="uid://g8idirw62qe0" path="res://player_controller/Scripts/Bobbing.cs" id="10_7wk1w"]
[ext_resource type="Resource" uid="uid://b5gx3q8nvu72e" path="res://systems/inputs/base_mode/hit.tres" id="11_cresl"]
[ext_resource type="PackedScene" uid="uid://0ysqmqphq6mq" path="res://systems/head/head_system.tscn" id="11_rxwoh"]
[ext_resource type="Resource" uid="uid://d2r0ur8k3cuu3" path="res://systems/inputs/base_mode/dash.tres" id="12_34snm"]
[ext_resource type="Script" uid="uid://b6k73aj5povgv" path="res://player_controller/Scripts/FieldOfView.cs" id="12_m2mxi"]
[ext_resource type="Resource" uid="uid://55b0dsvioj08" path="res://systems/inputs/base_mode/jump_pressed.tres" id="13_nob5r"]
[ext_resource type="Shape3D" uid="uid://keseacdcooot" path="res://player_controller/resources/PlayerShape.tres" id="13_r7i3q"]
[ext_resource type="Script" uid="uid://b5nk6ntlps3x0" path="res://systems/inputs/input_system.gd" id="16_v31n3"]
@@ -45,11 +47,6 @@
[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"]
[sub_resource type="Resource" id="Resource_jb43f"]
script = ExtResource("5_q7bng")
Modifier = 3.0
metadata/_custom_type_script = "uid://b6y3ugfydvch0"
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
height = 1.7
@@ -79,16 +76,16 @@ radius = 0.4
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"]
blend_mode = 1
[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("CDamage")]
[node name="Player" type="CharacterBody3D"]
collision_mask = 272
script = ExtResource("1_poq2x")
CDamage = NodePath("CDamageable")
WalkSpeed = 7.5
AccelerationFloor = 4.0
DecelerationFloor = 3.0
AccelerationAir = 0.8
DecelerationAir = 0.02
Weight = 4.0
MantleTime = 0.3
MantlePath = ExtResource("2_6lejt")
MantleDashStrength = 25.0
MantleJumpStartVelocity = 15.0
@@ -120,10 +117,14 @@ WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 4.0
WallHugHorizontalDeceleration = 1.0
[node name="CDamageable" type="Node" parent="."]
script = ExtResource("4_q7bng")
DamageModifiers = Array[Object]([SubResource("Resource_jb43f")])
metadata/_custom_type_script = "uid://b0u23nkpaimyc"
[node name="CHealth" parent="." instance=ExtResource("3_q7bng")]
RHealth = ExtResource("4_m8gvy")
[node name="CDamageable" parent="." instance=ExtResource("5_jb43f")]
DamageModifiers = Array[Object]([ExtResource("6_cmijs")])
[node name="CKnockback" parent="." instance=ExtResource("7_x835q")]
RKnockback = ExtResource("8_m8gvy")
[node name="WallRunSnapper" type="RayCast3D" parent="."]
unique_name_in_owner = true
@@ -174,6 +175,9 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
CameraInclineAcceleration = 20.0
GroundedCameraIncline = 3.0
SlidingJitterAmplitude = 0.2
WeaponSway = 8.0
WeaponLookRotation = 10.0
WeaponAdjustmentSpeed = 1.0
[node name="MantleSystem" parent="HeadSystem" instance=ExtResource("8_qu4wy")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0)
@@ -185,6 +189,7 @@ unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0)
collision_layer = 0
collision_mask = 16
monitoring = false
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="HeadSystem/WeaponHitbox"]
@@ -203,12 +208,6 @@ collision_mask = 256
target_position = Vector3(0, -0.75, 0)
collision_mask = 256
[node name="Bobbing" type="Node3D" parent="."]
script = ExtResource("10_7wk1w")
[node name="FieldOfView" type="Node3D" parent="."]
script = ExtResource("12_m2mxi")
[node name="HeadCollisionDetectors" type="Node3D" parent="."]
visible = false
@@ -277,11 +276,11 @@ collision_mask = 256
DashSpeed = 0.2
PostDashSpeed = 30.0
[node name="WeaponRoot" type="Node3D" parent="."]
[node name="WeaponSystem" parent="WeaponRoot" instance=ExtResource("29_wv70j")]
[node name="WeaponSystem" parent="." instance=ExtResource("29_wv70j")]
transform = Transform3D(1, 0, 0, 0, 0.173648, -0.984808, 0, 0.984808, 0.173648, 0.45268, 1.44035, -0.692528)
ThrowForce = 15.0
mass = 10.0
gravity_scale = 3.0
ThrowForce = 300.0
StraightThrowDuration = 0.05
[node name="DashIndicator" type="Node3D" parent="."]
@@ -306,6 +305,13 @@ collision_mask = 256
target_position = Vector3(0, -2, 0)
collision_mask = 256
[node name="InvincibilityTime" type="Timer" parent="."]
one_shot = true
[node name="AttackCooldown" type="Timer" parent="."]
wait_time = 0.3
one_shot = true
[node name="DashCooldown" type="Timer" parent="."]
wait_time = 0.8
one_shot = true

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using GodotStateCharts;
using Movementtests.addons.godot_state_charts.csharp;
@@ -9,7 +11,9 @@ using RustyOptions;
public partial class PlayerController : CharacterBody3D,
IDamageable,
IDamageDealer
IDamageDealer,
IHealthable,
IKnockbackable
{
// Enums
public enum AllowedInputs
@@ -36,19 +40,18 @@ public partial class PlayerController : CharacterBody3D,
///////////////////////////
public event Action<IDamageable, DamageRecord> DamageTaken;
public event Action<IHealthable, float> HealthChanged;
public event Action<IHealthable> HealthDepleted;
///////////////////////////
// Public stuff //
///////////////////////////
public HeadSystem HeadSystem;
public Bobbing Bobbing;
public FieldOfView FieldOfView;
public StairsSystem StairsSystem;
public MantleSystem MantleSystem;
public DashSystem DashSystem;
public CollisionShape3D StandingCollider;
public CollisionShape3D SlideCollider;
public Node3D WeaponRoot;
public WeaponSystem WeaponSystem;
public WallHugSystem WallHugSystem;
public PlayerUi PlayerUi;
@@ -71,9 +74,14 @@ public partial class PlayerController : CharacterBody3D,
[ExportGroup("Damage")]
[Export]
public RDamage RDamage { get; set; }
[Export]
public CDamageable CDamage { get; set; }
[Export]
public RKnockback RKnockback { get; set; }
[Export]
public RHealth RHealth { get; set; }
// Movement stuff
[ExportCategory("Movement")]
[ExportGroup("Ground")]
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
@@ -175,7 +183,6 @@ public partial class PlayerController : CharacterBody3D,
[Export(PropertyHint.Range, "1,10,0.1,or_greater")]
public float GroundSlideSlopeMagnetism = 2f;
[ExportSubgroup("Air glide")]
[Export]
public bool AllowForVelocityRedirection = true;
@@ -211,8 +218,7 @@ public partial class PlayerController : CharacterBody3D,
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunSpeedThreshold { get; set; } = 8f;
///////////////////////////
// Private stuff //
///////////////////////////
@@ -282,6 +288,8 @@ public partial class PlayerController : CharacterBody3D,
private Timer _simpleDashCooldownTimer;
private Timer _airborneDashCooldownTimer;
private Timer _powerCooldownTimer;
private Timer _invincibilityTimer;
private Timer _attackCooldown;
// State chart
private StateChart _playerState;
@@ -311,12 +319,25 @@ public partial class PlayerController : CharacterBody3D,
private StateChartState _onWallHanging;
private StateChartState _onWallRunning;
private Transition _onDashEnded;
private Transition _onJumpFromWall;
private Transition _onJumpFromWallFalling;
private Transition _onLeaveWallFromRun;
private Transition _onAirborneToGrounded;
private Transition _onGroundSlideJump;
private Transition _onAirGlideDoubleJump;
// Damage
public CDamageable CDamageable { get; set; }
public CHealth CHealth { get; set; }
public CKnockback CKnockback { get; set; }
public float CurrentHealth { get; set; }
private bool _isInvincible;
private bool _canAttack = true;
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>();
public override void _Ready()
{
@@ -340,14 +361,11 @@ public partial class PlayerController : CharacterBody3D,
// Camera stuff
HeadSystem = GetNode<HeadSystem>("HeadSystem");
Bobbing = GetNode<Bobbing>("Bobbing");
FieldOfView = GetNode<FieldOfView>("FieldOfView");
Camera3D camera = GetNode<Camera3D>("HeadSystem/CameraSmooth/Camera3D");
Node3D cameraSmooth = GetNode<Node3D>("HeadSystem/CameraSmooth");
// Movement stuff
WeaponRoot = GetNode<Node3D>("WeaponRoot");
WeaponSystem = GetNode<WeaponSystem>("WeaponRoot/WeaponSystem");
WeaponSystem = GetNode<WeaponSystem>("WeaponSystem");
MantleSystem = GetNode<MantleSystem>("HeadSystem/MantleSystem");
StandingCollider = GetNode<CollisionShape3D>("StandingCollider");
SlideCollider = GetNode<CollisionShape3D>("SlideCollider");
@@ -370,8 +388,29 @@ public partial class PlayerController : CharacterBody3D,
var playerShape = StandingCollider.GetShape() as CapsuleShape3D;
_playerHeight = playerShape!.Height;
_playerRadius = playerShape.Radius;
// Combat stuff
WeaponHitbox = GetNode<Area3D>("%WeaponHitbox");
WeaponHitbox.Monitoring = false;
WeaponHitbox.BodyEntered += RegisterHitEnnemy;
CHealth = GetNode<Node>("CHealth") as CHealth;
CKnockback = GetNode<Node>("CKnockback") as CKnockback;
CDamageable = GetNode<Node>("CDamageable") as CDamageable;
if (CHealth == null) throw new Exception("CHealth not found!");
if (CKnockback == null) throw new Exception("CKnockback not found!");
if (CDamageable == null) throw new Exception("CDamageable not found!");
if (RHealth != null)
{
CHealth.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth;
}
if (RKnockback != null) CKnockback!.RKnockback = RKnockback;
CDamageable.DamageTaken += ReduceHealth;
CDamageable.DamageTaken += RegisterKnockback;
CHealth.HealthDepleted += Kill;
// State management
_playerState = StateChart.Of(GetNode("StateChart"));
@@ -388,6 +427,7 @@ public partial class PlayerController : CharacterBody3D,
_airGlidingDoubleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled"));
_onGroundSlideJump = Transition.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide/OnJump"));
_onAirGlideDoubleJump = Transition.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled/OnJump"));
_onDashEnded = Transition.Of(GetNode("StateChart/Root/Movement/Dashing/OnDashEnded"));
// _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging"));
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
@@ -409,12 +449,15 @@ public partial class PlayerController : CharacterBody3D,
_onWallHanging = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging"));
_onWallRunning = StateChartState.Of(GetNode("StateChart/Root/Movement/OnWall/Running"));
_onLeaveWallFromRun = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnLeaveWall"));
_onAirborneToGrounded = Transition.Of(GetNode("StateChart/Root/Movement/Airborne/OnGrounded"));
// State timers
_powerCooldownTimer = GetNode<Timer>("PowerCooldown");
_timeScaleAimInAirTimer = GetNode<Timer>("TimeScaleAimInAir");
_simpleDashCooldownTimer = GetNode<Timer>("DashCooldown");
_airborneDashCooldownTimer = GetNode<Timer>("AirborneDashCooldown");
_invincibilityTimer = GetNode<Timer>("InvincibilityTime");
_attackCooldown = GetNode<Timer>("AttackCooldown");
///////////////////////////
// Initialize components //
@@ -422,8 +465,8 @@ public partial class PlayerController : CharacterBody3D,
// Camera stuff
HeadSystem.Init();
Bobbing.Init(camera);
FieldOfView.Init(camera);
HeadSystem.HitboxActivated += OnHitboxActivated;
HeadSystem.HitboxDeactivated += OnHitboxDeactivated;
// Movement stuff
// Getting universal setting from GODOT editor to be in sync
@@ -442,6 +485,9 @@ public partial class PlayerController : CharacterBody3D,
///////////////////////////
// Signal setup ///////////
///////////////////////////
_invincibilityTimer.Timeout += ResetInvincibility;
_attackCooldown.Timeout += ResetAttackCooldown;
_aiming.StatePhysicsProcessing += HandleAiming;
_aiming.StateEntered += OnAimingEntered;
_aiming.StateExited += ResetTimeScale;
@@ -501,9 +547,13 @@ public partial class PlayerController : CharacterBody3D,
_onWallHanging.StatePhysicsProcessing += HandleWallHanging;
_onWallRunning.StatePhysicsProcessing += HandleWallRunning;
_onWallHanging.StateExited += RecoverWeapon;
_onDashEnded.Taken += RecoverWeapon;
_onJumpFromWall.Taken += OnJumpFromWall;
_onJumpFromWallFalling.Taken += OnJumpFromWall;
_onLeaveWallFromRun.Taken += OnLeaveWallFromRun;
_onAirborneToGrounded.Taken += OnAirborneToGrounded;
}
///////////////////////////
@@ -548,9 +598,9 @@ public partial class PlayerController : CharacterBody3D,
if (TutorialDone)
return;
RemoveChild(WeaponRoot);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponRoot);
WeaponRoot.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition);
RemoveChild(WeaponSystem);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponSystem);
WeaponSystem.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition);
WeaponSystem.CallDeferred(WeaponSystem.MethodName.PlaceWeaponForTutorial, TutorialWeaponTarget.GlobalPosition);
}
@@ -598,6 +648,11 @@ public partial class PlayerController : CharacterBody3D,
}
}
public void OnAirborneToGrounded()
{
HeadSystem.OnJumpEnded();
}
public bool IsGroundLike()
{
return GroundDetector.GetCollisionResult().Count > 0;
@@ -811,39 +866,25 @@ public partial class PlayerController : CharacterBody3D,
var lookSensitivity = _isUsingGamepad ? _lookSensitivityMultiplier : _mouseSensitivityMultiplier;
var wallHugContactPoint = _onWallRunning.Active ? _currentWallContactPoint : Vector3.Zero;
var playerVelocity = GetGlobalMoveInput();
HeadSystem.LookAround(delta, inputLookDir, playerVelocity, Velocity, wallHugContactPoint, lookSensitivity, isSliding: _groundSliding.Active);
}
public void RotateWeaponWithPlayer()
{
WeaponRoot.SetRotation(HeadSystem.Rotation);
var moveInput = GetGlobalMoveInput();
var lookAroundInputs = new HeadSystem.CameraParameters(
Delta: delta,
LookDir: inputLookDir,
PlayerInput: moveInput,
PlayerVelocity:Velocity,
WallContactPoint: wallHugContactPoint,
SensitivitMultiplier: lookSensitivity,
WithCameraJitter: _groundSliding.Active,
WithCameraBobbing: _grounded.Active || _onWallRunning.Active,
BobbingMultiplier: _headBobbingMultiplier,
FovMultiplier: _fovChangeMultiplier);
HeadSystem.LookAround(lookAroundInputs);
}
public Vector3 GetGlobalForwardFacingVector()
{
return Transform.Basis * HeadSystem.Transform.Basis * Vector3.Forward;
}
private void CameraModifications(float delta)
{
Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams
{
Delta = delta,
IsOnFloorCustom = _grounded.Active || _onWallRunning.Active,
Velocity = Velocity,
SettingsMultiplier = _headBobbingMultiplier
};
Bobbing.PerformCameraBobbing(cameraBobbingParams);
FieldOfView.FovParameters fovParams = new FieldOfView.FovParameters
{
IsCrouchingHeight = false,
Delta = delta,
SprintSpeed = WalkSpeed,
Velocity = Velocity,
FOVMultiplier = _fovChangeMultiplier
};
FieldOfView.PerformFovAdjustment(fovParams);
}
// Horizontal velocity computing
public Vector3 ComputeHVelocity(float delta, float accelerationFactor, float decelerationFactor, Vector3? direction = null)
{
@@ -1122,7 +1163,8 @@ public partial class PlayerController : CharacterBody3D,
_playerState.SendEvent("mantle");
return;
}
HeadSystem.OnJumpStarted();
if (WallHugSystem.IsWallHugging())
{
_playerState.SendEvent("wall_jump");
@@ -1247,11 +1289,10 @@ public partial class PlayerController : CharacterBody3D,
_mantlePath.Setup(transform, curve);
_mantleStartPosition = GlobalPosition;
var curveLength = curve.GetBakedLength();
var tween = GetTree().CreateTween();
tween.SetTrans(Tween.TransitionType.Linear);
tween.SetEase(Tween.EaseType.In);
tween.TweenProperty(_mantlePath.PathFollow, "progress_ratio", 1, MantleTime*curveLength);
tween.TweenProperty(_mantlePath.PathFollow, "progress_ratio", 1, MantleTime);
tween.Finished += MantleFinished;
}
public void HandleMantling(float delta)
@@ -1283,6 +1324,7 @@ public partial class PlayerController : CharacterBody3D,
///////////////////////////
private bool _isSlideInputDown = false;
public void OnInputSlideStarted()
{
_isSlideInputDown = true;
@@ -1570,9 +1612,6 @@ public partial class PlayerController : CharacterBody3D,
}
public void HandleAiming(float delta)
{
if (WeaponSystem.InHandState.Active)
RotateWeaponWithPlayer();
DashIndicatorMeshCylinder.Height = DashSystem.PlannedLocation.DistanceTo(GlobalPosition);
DashIndicatorNode.LookAt(DashSystem.PlannedLocation);
@@ -1640,7 +1679,8 @@ public partial class PlayerController : CharacterBody3D,
public void ThrowWeapon()
{
_playerState.SendEvent("cancel_aim");
RemoveChildNode(WeaponRoot);
RemoveChildNode(WeaponSystem);
HeadSystem.HideWeapon();
var weaponTargetLocation = DashSystem.HasHit ? DashSystem.CollisionPoint : DashSystem.PlannedLocation;
WeaponSystem.ThrowWeapon(
@@ -1651,7 +1691,10 @@ public partial class PlayerController : CharacterBody3D,
}
public void RecoverWeapon()
{
RecoverChildNode(WeaponRoot);
if (WeaponSystem.GetParent() == this) return;
HeadSystem.ShowWeapon();
RecoverChildNode(WeaponSystem);
WeaponSystem.ResetWeapon();
}
@@ -1704,8 +1747,6 @@ public partial class PlayerController : CharacterBody3D,
var isPlantedUnderPlatform = WeaponSystem.IsPlantedUnderPlatform();
var shouldDashToHanging = isPlantedOnWall || isPlantedUnderPlatform;
RecoverWeapon();
var resultingEvent = shouldDashToHanging ? "dash_to_planted" : "dash_finished";
_playerState.SendEvent(resultingEvent);
}
@@ -1718,12 +1759,10 @@ public partial class PlayerController : CharacterBody3D,
if (_currentInputBufferFrames > 0) _currentInputBufferFrames -= 1;
LookAround(delta);
CameraModifications((float) delta);
Velocity += ComputeKnockback();
MoveSlideAndHandleStairs((float) delta);
MantleSystem.ProcessMantle(_grounded.Active);
if (WeaponSystem.InHandState.Active)
RotateWeaponWithPlayer();
if (WeaponSystem.InHandState.Active && !_aiming.Active && TutorialDone)
{
DashIndicatorMesh.Visible = false;
@@ -1736,17 +1775,25 @@ public partial class PlayerController : CharacterBody3D,
DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition);
}
}
public DamageRecord TakeDamage(DamageRecord damageRecord)
{
var finalDamage = CDamage.TakeDamage(damageRecord);
DamageTaken?.Invoke(this, finalDamage);
return finalDamage;
}
///////////////////////////
// Hit Management ///////
///////////////////////////
public DamageRecord TakeDamage(DamageRecord damageRecord)
{
if (_isInvincible)
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
var finalDamage = CDamageable.TakeDamage(damageRecord);
DamageTaken?.Invoke(this, finalDamage);
TriggerHitstop();
_isInvincible = true;
_invincibilityTimer.Start();
return finalDamage;
}
public void OnInputHitPressed()
{
if (_aiming.Active && WeaponSystem.InHandState.Active)
@@ -1755,11 +1802,82 @@ public partial class PlayerController : CharacterBody3D,
}
if (!WeaponSystem.InHandState.Active) return;
var bodies = WeaponHitbox.GetOverlappingBodies();
foreach (var body in bodies)
{
if(body is IDamageable spawnable)
spawnable.TakeDamage(new DamageRecord(this, RDamage));
}
if (!_canAttack) return;
_canAttack = false;
_attackCooldown.Start();
PerformHit();
}
public void ResetAttackCooldown()
{
_canAttack = true;
}
public void PerformHit()
{
HeadSystem.OnHit();
}
public void OnHitboxActivated()
{
WeaponHitbox.Monitoring = true;
}
public void OnHitboxDeactivated()
{
WeaponHitbox.Monitoring = false;
TriggerDamage();
}
public void RegisterHitEnnemy(Node3D body)
{
if (body is not IDamageable damageable) return;
_hitEnemies.Add(damageable);
}
public void TriggerDamage()
{
if (_hitEnemies.Count == 0) return;
foreach (var damageable in _hitEnemies)
damageable.TakeDamage(new DamageRecord(this, RDamage));
_hitEnemies.Clear();
TriggerHitstop();
}
public void TriggerHitstop()
{
Engine.SetTimeScale(0.01);
var timer = GetTree().CreateTimer(0.1, true, false, true);
timer.Timeout += OnHitstopEnded;
}
public void OnHitstopEnded()
{
ResetTimeScale();
}
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
{
CHealth.ReduceHealth(source, damageRecord);
HealthChanged?.Invoke(this, CHealth.CurrentHealth);
}
public void RegisterKnockback(IDamageable source, DamageRecord damageRecord)
{
CKnockback.RegisterKnockback(source, damageRecord);
}
public Vector3 ComputeKnockback()
{
return CKnockback.ComputeKnockback();
}
public void Kill(IHealthable source)
{
GD.Print("Player died!");
}
public void ResetInvincibility()
{
_isInvincible = false;
}
}

View File

@@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="RHealth" load_steps=2 format=3 uid="uid://bjyd801wvverk"]
[ext_resource type="Script" uid="uid://baiapod3csndf" path="res://components/health/RHealth.cs" id="1_tv6ah"]
[resource]
script = ExtResource("1_tv6ah")
metadata/_custom_type_script = "uid://baiapod3csndf"

View File

@@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="RKnockback" load_steps=2 format=3 uid="uid://bs8b0oojixm4q"]
[ext_resource type="Script" uid="uid://b44cse62qru7j" path="res://components/knockback/RKnockback.cs" id="1_dthjm"]
[resource]
script = ExtResource("1_dthjm")
Modifier = 30.0
metadata/_custom_type_script = "uid://b44cse62qru7j"

View File

@@ -0,0 +1,7 @@
[gd_resource type="Resource" script_class="RDamageModifier" load_steps=2 format=3 uid="uid://dyru7mxo121w6"]
[ext_resource type="Script" uid="uid://b6y3ugfydvch0" path="res://components/damage/RDamageModifier.cs" id="1_7i47t"]
[resource]
script = ExtResource("1_7i47t")
metadata/_custom_type_script = "uid://b6y3ugfydvch0"

View File

@@ -73,7 +73,6 @@ public partial class Enemy : CharacterBody3D,
public void SetupSignals()
{
_damageBox.BodyEntered += OnDamageBoxTriggered;
if (CDamage is IDamageable damageable)
{
damageable.DamageTaken += ReduceHealth;
@@ -84,6 +83,9 @@ public partial class Enemy : CharacterBody3D,
public override void _PhysicsProcess(double delta)
{
// Only trigger gameplay related effects 4 times per second
if(Engine.GetPhysicsFrames() % 15 == 0) ProcessGameplay(delta);
var targetPlanar = new Vector3(Target.GlobalPosition.X, GlobalPosition.Y, Target.GlobalPosition.Z);
LookAt(targetPlanar);
@@ -98,6 +100,16 @@ public partial class Enemy : CharacterBody3D,
Velocity += ComputeKnockback();
MoveAndSlide();
}
public void ProcessGameplay(double delta)
{
var bodies = _damageBox.GetOverlappingBodies();
foreach (var body in bodies)
{
if(body is IDamageable spawnable)
spawnable.TakeDamage(new DamageRecord(this, RDamage));
}
}
public Vector3 ComputeVelocity(MovementInputs inputs)
{
@@ -105,14 +117,6 @@ public partial class Enemy : CharacterBody3D,
return movement!.ComputeVelocity(inputs);
}
public void OnDamageBoxTriggered(Node3D body)
{
if (body is not IDamageable damageable) return;
var damageRecord = new DamageRecord(this, RDamage);
damageable.TakeDamage(damageRecord);
}
public DamageRecord TakeDamage(DamageRecord damageRecord)
{
if (CDamage is not IDamageable damageable)
@@ -120,8 +124,6 @@ public partial class Enemy : CharacterBody3D,
var finalDamage = damageable.TakeDamage(damageRecord);
DamageTaken?.Invoke(this, finalDamage);
GD.Print($"Received damage: {finalDamage.Damage.DamageDealt}");
return finalDamage;
}
@@ -129,6 +131,7 @@ public partial class Enemy : CharacterBody3D,
{
if (CHealth is not IHealthable healthable) return;
healthable.ReduceHealth(source, damageRecord);
HealthChanged?.Invoke(this, healthable.CurrentHealth);
}
public void Kill(IHealthable source)

View File

@@ -41,7 +41,6 @@ rings = 4
albedo_color = Color(0.06469653, 0.06469653, 0.06469653, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_4yfjf"]
size = Vector3(1, 1, 1.5)
[node name="FlyingEnemy" type="CharacterBody3D" node_paths=PackedStringArray("CHealth", "CDamage", "CKnockback", "CMovement")]
collision_layer = 16
@@ -107,5 +106,5 @@ collision_layer = 0
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="DamageBox"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.75)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.5)
shape = SubResource("BoxShape3D_4yfjf")

View File

@@ -4,5 +4,5 @@
[resource]
script = ExtResource("1_yq03x")
Modifier = 10.0
Modifier = 20.0
metadata/_custom_type_script = "uid://b44cse62qru7j"

View File

@@ -36,7 +36,7 @@ rings = 4
albedo_color = Color(0.06469653, 0.06469653, 0.06469653, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_4yfjf"]
size = Vector3(1, 2, 2)
size = Vector3(1, 2, 1.5)
[node name="GroundedEnemy" type="CharacterBody3D" node_paths=PackedStringArray("CHealth", "CDamage", "CKnockback", "CMovement")]
collision_layer = 16
@@ -103,5 +103,5 @@ collision_layer = 0
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="DamageBox"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0.5)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0.25)
shape = SubResource("BoxShape3D_4yfjf")

View File

@@ -4,5 +4,5 @@
[resource]
script = ExtResource("1_vdia8")
Modifier = 10.0
Modifier = 30.0
metadata/_custom_type_script = "uid://b44cse62qru7j"

View File

@@ -6,32 +6,87 @@ namespace Movementtests.systems;
public partial class HeadSystem : Node3D
{
[Signal]
public delegate void HitboxActivatedEventHandler();
[Signal]
public delegate void HitboxDeactivatedEventHandler();
public record CameraParameters(
double Delta,
Vector2 LookDir,
Vector3 PlayerInput,
Vector3 PlayerVelocity,
Vector3 WallContactPoint,
float SensitivitMultiplier,
bool WithCameraJitter,
bool WithCameraBobbing,
float BobbingMultiplier,
float FovMultiplier);
private Camera3D _camera;
private Marker3D _cameraAnchor;
private AnimationPlayer _animationPlayer;
private AnimationTree _animationTree;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float LookSensitivity { get; set; } = 1f;
[ExportGroup("Camera incline")]
[Export(PropertyHint.Range, "0.1,50,0.1,or_greater")]
public double CameraInclineAcceleration { get; set; } = 10f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float WallRunCameraIncline { get; set; } = 5f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float GroundedCameraIncline { get; set; } = 5f;
[ExportGroup("Sliding")]
[Export(PropertyHint.Range, "0,2,0.1,or_greater")]
public float SlidingCameraHeightOffset { get; set; } = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float SlidingJitterFrequency { get; set; } = 0.01f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float SlidingJitterAmplitude { get; set; } = 0.1f;
private FastNoiseLite _slidingNoise = new FastNoiseLite();
[ExportGroup("Bobbing")]
private float _bobbingAccumulator; // Constantly increases when player moves in X or/and Z axis
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float BobbingFrequency { set; get; } = 2.4f;
[Export(PropertyHint.Range, "0,0.4,0.01,or_greater")]
public float BobbingAmplitude { set; get; } = 0.08f;
[ExportGroup("FOV")]
[Export(PropertyHint.Range, "0,180,0.1,degrees")]
public float BaseFov { get; set; } = 75.0f;
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float FovChangeFactor { get; set; } = 1.2f;
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float FovChangeSpeed { get; set; } = 6.25f;
[Export(PropertyHint.Range, "0,100,1,or_greater")]
public float FovMaxedOutSpeed { get; set; } = 20f;
[ExportGroup("First Person rig")]
private Node3D _fpRig;
private Node3D _fpDisplacedRig;
private Vector3 _fpDisplacedRigInitialRotation;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float WeaponSway { get; set; } = 5f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float WeaponLookRotation { get; set; } = 1f;
[Export(PropertyHint.Range, "0,200,1,or_greater")]
public float WeaponMoveRotation { get; set; } = 80f;
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float WeaponAdjustmentSpeed { get; set; } = 10f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float DisplacedWeaponSway { get; set; } = 5f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float DisplacedWeaponLookRotation { get; set; } = 1f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float DisplacedWeaponMoveRotation { get; set; } = 0.1f;
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float DisplacedWeaponAdjustmentSpeed { get; set; } = 10f;
public void Init()
{
@@ -39,18 +94,55 @@ public partial class HeadSystem : Node3D
_camera = GetNode<Camera3D>("CameraSmooth/Camera3D");
_cameraAnchor = GetNode<Marker3D>("CameraAnchor");
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
_animationTree = GetNode<AnimationTree>("AnimationTree");
_fpRig = GetNode<Node3D>("FPRig");
_fpDisplacedRig = GetNode<Node3D>("FPRig/Sword");
_fpDisplacedRigInitialRotation = _fpDisplacedRig.Rotation;
_slidingNoise.NoiseType = FastNoiseLite.NoiseTypeEnum.Perlin;
_slidingNoise.SetFrequency(SlidingJitterFrequency);
}
public void OnMantle()
{
_animationPlayer.Play("mantle");
_animationTree.Set("parameters/OnMantle/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
}
public void OnJumpStarted()
{
_animationTree.Set("parameters/OnJumpStart/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
}
public void OnJumpEnded()
{
_animationTree.Set("parameters/OnJumpEnd/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
}
public void OnHit()
{
_animationTree.Set("parameters/OnHit/request", (int) AnimationNodeOneShot.OneShotRequest.Fire);
}
public void LookAround(double delta, Vector2 lookDir, Vector3 playerInput, Vector3 playerVelocity, Vector3? wallContactPoint = null, float sensitivitMultiplier = 1f, bool isSliding = false)
public void OnHitboxActivated()
{
EmitSignalHitboxActivated();
}
public void OnHitboxDeactivated()
{
EmitSignalHitboxDeactivated();
}
public void LookAround(CameraParameters inputs)
{
var (delta,
lookDir,
playerInput,
playerVelocity,
wallContactPoint,
sensitivitMultiplier,
withCameraJitter,
withCameraBobbing,
bobbingMultiplier,
fovMultiplier) = inputs;
// Horizontal movement of head
float angleForHorizontalRotation = lookDir.X * LookSensitivity * sensitivitMultiplier;
RotateY(angleForHorizontalRotation);
@@ -61,11 +153,11 @@ public partial class HeadSystem : Node3D
currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f));
// Camera incline on Wall and more
var isWallRunning = wallContactPoint.HasValue && wallContactPoint.Value.Length() > Mathf.Epsilon;
var isWallRunning = wallContactPoint.Length() > Mathf.Epsilon;
float cameraIncline;
if (isWallRunning)
{
var directionToWall = (wallContactPoint.Value - GlobalPosition).Normalized();
var directionToWall = (wallContactPoint - GlobalPosition).Normalized();
var cameraInclineFactor = ComputeCameraInclineFactor(directionToWall);
cameraIncline = Mathf.DegToRad(WallRunCameraIncline * cameraInclineFactor);
}
@@ -77,7 +169,7 @@ public partial class HeadSystem : Node3D
currentCameraRotation.Z = (float) Mathf.Lerp(currentCameraRotation.Z, cameraIncline, delta * CameraInclineAcceleration);
_cameraAnchor.Rotation = currentCameraRotation;
if (isSliding)
if (withCameraJitter)
{
_cameraAnchor.Position = Vector3.Down*SlidingCameraHeightOffset;
float noise1D = _slidingNoise.GetNoise1D(Time.GetTicksMsec());
@@ -89,7 +181,79 @@ public partial class HeadSystem : Node3D
_cameraAnchor.Position = Vector3.Zero;
}
Vector3 newPositionForCamera = Vector3.Zero;
Vector3 newPositionForRig = Vector3.Zero;
if (withCameraBobbing)
{
_bobbingAccumulator += (float) delta * playerVelocity.Length();
// As the _bobbingAccumulator increases we're changing values for sin and cos functions.
// Because both of them are just waves, we will be slide up with y and then slide down with y
// creating bobbing effect. The same works for cos. As the _bobbingAccumulator increases the cos decreases and then increases
newPositionForCamera.Y = Mathf.Sin(_bobbingAccumulator * BobbingFrequency) * BobbingAmplitude * bobbingMultiplier;
newPositionForCamera.X = Mathf.Cos(_bobbingAccumulator * BobbingFrequency / 2.0f) * BobbingAmplitude * bobbingMultiplier;
// Offset bobbing for weapon rig
newPositionForRig.Y = Mathf.Cos(_bobbingAccumulator * BobbingFrequency) * BobbingAmplitude * bobbingMultiplier * 0.2f;
newPositionForRig.X = Mathf.Sin(_bobbingAccumulator * BobbingFrequency / 2.0f) * BobbingAmplitude * bobbingMultiplier * 0.2f;
}
_cameraAnchor.Position += newPositionForCamera;
_camera.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated();
// First person rig adjustments
_fpRig.GlobalTransform = _cameraAnchor.GetGlobalTransformInterpolated();
// Apply bobbing
_fpRig.Position += newPositionForRig;
// Rotate the whole rig based on movement input
var newRigRotation = _fpRig.Rotation;
var camTilt = Mathf.Lerp(_fpRig.Rotation.Z, cameraIncline*WeaponMoveRotation, delta*WeaponAdjustmentSpeed);
newRigRotation.Z = (float) camTilt;
// Rotate the whole rig based on camera rotation input
newRigRotation.X = Mathf.Lerp(newRigRotation.X, -lookDir.Y*WeaponSway, (float) delta*WeaponAdjustmentSpeed);
newRigRotation.Y = Mathf.Lerp(newRigRotation.Y, -lookDir.X*WeaponSway, (float) delta*WeaponAdjustmentSpeed);
// Apply
_fpRig.Rotation = newRigRotation;
// Compute displaced rig adjustments, starting with movement input
var newDisplacedRigRotation = _fpDisplacedRig.Rotation;
var howMuchForward = ComputeHowMuchInputForward(playerInput);
var howMuchSideways = ComputeHowMuchInputSideways(playerInput);
var displacedCamTiltForward = Mathf.Lerp(newDisplacedRigRotation.Z,
_fpDisplacedRigInitialRotation.Z + howMuchForward*DisplacedWeaponMoveRotation,
delta*DisplacedWeaponAdjustmentSpeed);
var displacedCamTiltSide = Mathf.Lerp(newDisplacedRigRotation.X,
_fpDisplacedRigInitialRotation.X - howMuchSideways*DisplacedWeaponMoveRotation,
delta*DisplacedWeaponAdjustmentSpeed);
newDisplacedRigRotation.X = (float) displacedCamTiltSide;
newDisplacedRigRotation.Z = (float) displacedCamTiltForward;
var displacedSwayY = Mathf.Lerp(newDisplacedRigRotation.Y,
_fpDisplacedRigInitialRotation.Y - lookDir.X*DisplacedWeaponSway,
delta*DisplacedWeaponAdjustmentSpeed);
newDisplacedRigRotation.Y = (float) displacedSwayY;
// Apply
_fpDisplacedRig.Rotation = newDisplacedRigRotation;
// Camera adjustments
float velocityClamped = Mathf.Clamp(playerVelocity.Length(), 0.5f, FovMaxedOutSpeed);
float targetFov = BaseFov + FovChangeFactor * velocityClamped * fovMultiplier;
_camera.Fov = Mathf.Lerp(_camera.Fov, targetFov, (float) delta * FovChangeSpeed);
}
public void HideWeapon()
{
_fpRig.Visible = false;
}
public void ShowWeapon()
{
_fpRig.Visible = true;
}
public float ComputeCameraInclineFactor(Vector3 direction)
@@ -99,6 +263,20 @@ public partial class HeadSystem : Node3D
return crossProduct.Length()*Mathf.Sign(crossProduct.Y);
}
public float ComputeHowMuchInputForward(Vector3 playerInput)
{
var forwardAngle = GetForwardHorizontalVector().AngleTo(playerInput);
var forwardRemapped = Mathf.Remap(forwardAngle, 0, Mathf.Pi, -1, 1);
return playerInput.Length() > 0 ? forwardRemapped : 0;
}
public float ComputeHowMuchInputSideways(Vector3 playerInput)
{
var rightAngle = GetForwardHorizontalVector().Cross(Vector3.Up).Normalized().AngleTo(playerInput);
var forwardRemapped = Mathf.Remap(rightAngle, 0, Mathf.Pi, -1, 1);
return playerInput.Length() > 0 ? forwardRemapped : 0;
}
public Vector3 GetForwardHorizontalVector()
{
return GetGlobalTransform().Basis.Z;

View File

@@ -0,0 +1,57 @@
[gd_resource type="AnimationNodeBlendTree" load_steps=11 format=3 uid="uid://c26yvcyyyj811"]
[ext_resource type="AnimationNodeStateMachine" uid="uid://3r5oeg0ho0d4" path="res://systems/head/fp_state_machine.tres" id="1_knaxl"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_knaxl"]
animation = &"idle"
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_1hkum"]
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_knaxl"]
filter_enabled = true
filters = ["..:position", "..:rotation"]
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_23rmc"]
filter_enabled = true
filters = ["..:position", "..:rotation"]
[sub_resource type="AnimationNodeOneShot" id="AnimationNodeOneShot_dlkjl"]
filter_enabled = true
filters = ["..:position", "..:rotation", "..:rotation:x", "..:rotation:z"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_23rmc"]
animation = &"hit1"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_dlkjl"]
animation = &"jump_end"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ao3u1"]
animation = &"jump_start"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_lwjon"]
animation = &"mantle"
[resource]
graph_offset = Vector2(-223.13931, -84.56735)
nodes/output/position = Vector2(1540, 0)
nodes/AnimationNodeStateMachine/node = ExtResource("1_knaxl")
nodes/AnimationNodeStateMachine/position = Vector2(-560, 180)
nodes/Idle/node = SubResource("AnimationNodeAnimation_knaxl")
nodes/Idle/position = Vector2(-100, -20)
nodes/OnHit/node = SubResource("AnimationNodeOneShot_1hkum")
nodes/OnHit/position = Vector2(1240, -60)
nodes/hit1/node = SubResource("AnimationNodeAnimation_23rmc")
nodes/hit1/position = Vector2(1080, 320)
nodes/OnJumpStart/node = SubResource("AnimationNodeOneShot_23rmc")
nodes/OnJumpStart/position = Vector2(140, 0)
nodes/OnJumpEnd/node = SubResource("AnimationNodeOneShot_knaxl")
nodes/OnJumpEnd/position = Vector2(560, -20)
nodes/jump_start/node = SubResource("AnimationNodeAnimation_ao3u1")
nodes/jump_start/position = Vector2(-120, 320)
nodes/jump_end/node = SubResource("AnimationNodeAnimation_dlkjl")
nodes/jump_end/position = Vector2(300, 340)
nodes/OnMantle/node = SubResource("AnimationNodeOneShot_dlkjl")
nodes/OnMantle/position = Vector2(900, -60)
nodes/mantle/node = SubResource("AnimationNodeAnimation_lwjon")
nodes/mantle/position = Vector2(640, 320)
node_connections = [&"output", 0, &"OnHit", &"OnHit", 0, &"OnMantle", &"OnHit", 1, &"hit1", &"OnJumpStart", 0, &"Idle", &"OnJumpStart", 1, &"jump_start", &"OnJumpEnd", 0, &"OnJumpStart", &"OnJumpEnd", 1, &"jump_end", &"OnMantle", 0, &"OnJumpEnd", &"OnMantle", 1, &"mantle"]

View File

@@ -0,0 +1,14 @@
[gd_resource type="AnimationNodeStateMachine" load_steps=3 format=3 uid="uid://3r5oeg0ho0d4"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_73q32"]
animation = &"idle"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_adm0b"]
advance_mode = 2
[resource]
states/Start/position = Vector2(100, 91)
states/idle/node = SubResource("AnimationNodeAnimation_73q32")
states/idle/position = Vector2(331, 91)
transitions = ["Start", "idle", SubResource("AnimationNodeStateMachineTransition_adm0b")]
graph_offset = Vector2(-82, -9)

View File

@@ -1,68 +1,271 @@
[gd_scene load_steps=5 format=3 uid="uid://0ysqmqphq6mq"]
[gd_scene load_steps=11 format=3 uid="uid://0ysqmqphq6mq"]
[ext_resource type="Script" uid="uid://dtkdrnsmlwm67" path="res://systems/head/HeadSystem.cs" id="1_8abgy"]
[ext_resource type="ArrayMesh" uid="uid://ckr26s4e3fj1m" path="res://assets/swords/resources/fp_sword23.tres" id="2_c5qep"]
[ext_resource type="AnimationNodeBlendTree" uid="uid://c26yvcyyyj811" path="res://systems/head/fp_blend_tree.tres" id="3_r0h40"]
[sub_resource type="Animation" id="Animation_urko7"]
length = 0.001
tracks/0/type = "bezier"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("..:rotation:x")
tracks/0/path = NodePath("../../FPRig/Sword:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.15, 0, 0.15, 0),
"times": PackedFloat32Array(0)
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0.53640664, -0.7880347, -1.9288678)]
}
tracks/1/type = "bezier"
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("..:rotation:z")
tracks/1/path = NodePath("../../FPRig/Sword:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.15, 0, 0.15, 0),
"times": PackedFloat32Array(0)
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(-0.083978735, -1.136043, 0.19867715)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../../FPRig/Sword:scale")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(1.0000001, 1.0000001, 1.0000005)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("..:rotation")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0.00011616433)]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("..:position")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_r0h40"]
resource_name = "hit1"
length = 0.30000168
step = 0.016666668
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("../../FPRig/Sword:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.11666667, 0.15, 0.21666667, 0.3),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector3(0.53640664, -0.7880347, -1.9288678), Vector3(0.4045868, -0.4412415, -1.5352597), Vector3(-0.4799922, -0.5403832, -1.6861614), Vector3(-0.46995986, -0.53766656, -1.3638693), Vector3(-0.49520528, -0.5369735, -1.3145388), Vector3(-0.4048354, -0.5878634, -1.2836416)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../../FPRig/Sword:rotation")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.11666667, 0.15, 0.21666667, 0.3),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector3(-0.083978735, -1.136043, 0.19867715), Vector3(-0.7788485, -2.0049822, -0.2951485), Vector3(-0.94931036, -0.5881021, -0.61733377), Vector3(-1.3252386, -0.102411434, 0.58406436), Vector3(-1.2938086, -0.18945412, 0.7334958), Vector3(-1.1484056, -0.2900904, 0.6867544)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../../FPRig/Sword:scale")
tracks/2/interp = 2
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.11666667, 0.15, 0.21666667, 0.3),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector3(1.0000001, 1.0000001, 1.0000005), Vector3(1, 1.0004268, 1.0000002), Vector3(0.99999994, 1.2493719, 0.99999976), Vector3(1.0000001, 1.1750004, 1.0000004), Vector3(0.99999994, 0.99999994, 0.99999994), Vector3(1.0000001, 0.9999999, 1)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("..:rotation")
tracks/3/interp = 2
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.083333336, 0.11666667, 0.2, 0.23333333, 0.3),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0.00011616433), Vector3(0, -0.02617994, -0.02617994), Vector3(0, 0.02617994, 0.02617994), Vector3(0, 0, 0)]
}
tracks/4/type = "method"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("../..")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0.083333336, 0.23333333),
"transitions": PackedFloat32Array(1, 1),
"values": [{
"args": [],
"method": &"OnHitboxActivated"
}, {
"args": [],
"method": &"OnHitboxDeactivated"
}]
}
[sub_resource type="Animation" id="Animation_0hyrq"]
resource_name = "idle"
length = 2.0
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("../../FPRig/Sword:position")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3, 0.6, 1, 1.4),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [Vector3(0.53640664, -0.7880347, -1.9288678), Vector3(0.53640664, -0.83580256, -1.9288678), Vector3(0.53640664, -0.86088884, -1.9288678), Vector3(0.53640664, -0.8256072, -1.9288678), Vector3(0.53640664, -0.7880347, -1.9288678)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../../FPRig/Sword:rotation")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.3, 0.6, 1, 1.4),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
"update": 0,
"values": [Vector3(-0.083978735, -1.136043, 0.19867715), Vector3(-0.06987281, -1.1365474, 0.20524277), Vector3(-0.05990464, -1.1368362, 0.20987195), Vector3(-0.06303402, -1.1367121, 0.2084137), Vector3(-0.083978735, -1.136043, 0.19867715)]
}
[sub_resource type="Animation" id="Animation_1ay6d"]
resource_name = "jump_end"
length = 0.26667002
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("..:rotation")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.13333334, 0.26666668),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(0, 0, 0.00011616433), Vector3(-0.08726646, 0, 0), Vector3(0, 0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("..:position")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.26666668),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(0, -0.05, 0), Vector3(0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_ubhf8"]
resource_name = "jump_start"
length = 0.26667002
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("..:position")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.26666668),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(0, -0.1, 0), Vector3(0, 0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("..:rotation")
tracks/1/interp = 2
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.13333334, 0.26666668),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(0, 0, 0.00011616433), Vector3(-0.08726646, 0, 0), Vector3(0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_8abgy"]
resource_name = "mantle"
length = 0.3
tracks/0/type = "bezier"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("..:rotation:x")
tracks/0/interp = 1
tracks/0/path = NodePath("..:rotation")
tracks/0/interp = 2
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(2, 2, 2),
"points": PackedFloat32Array(0, 0, 0, 0.050000004, 0, -0.17453292, -0.050000004, 0, 0.050000004, 0, 0, -0.050000004, 0, 0, 0),
"times": PackedFloat32Array(0, 0.15, 0.3)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("..:rotation:z")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(2, 2, 2, 2),
"points": PackedFloat32Array(0.00011616433, 0, 0, 0.033333335, 0, -0.05235988, -0.033333335, 0, 0.033333335, 0, 0.05235988, -0.033333335, 0, 0.03333334, 0, 0, -0.03333334, 0, 0, 0),
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3)
"times": PackedFloat32Array(0, 0.1, 0.3),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(0, 0, 0.00011616433), Vector3(-1.0471976, 0, 0), Vector3(0, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_0hyrq"]
_data = {
&"RESET": SubResource("Animation_urko7"),
&"hit1": SubResource("Animation_r0h40"),
&"idle": SubResource("Animation_0hyrq"),
&"jump_end": SubResource("Animation_1ay6d"),
&"jump_start": SubResource("Animation_ubhf8"),
&"mantle": SubResource("Animation_8abgy")
}
[node name="HeadSystem" type="Node3D"]
script = ExtResource("1_8abgy")
WeaponMoveRotation = 20.0
DisplacedWeaponSway = 1.0
DisplacedWeaponAdjustmentSpeed = 8.0
[node name="FPRig" type="Node3D" parent="."]
[node name="Sword" type="Node3D" parent="FPRig"]
transform = Transform3D(0.42791694, -0.008550272, -0.9037781, 0.19667713, 0.9768738, 0.0838801, 0.88215953, -0.2136461, 0.41970265, 0.53640664, -0.7880347, -1.9288678)
[node name="SwordMesh" type="MeshInstance3D" parent="FPRig/Sword"]
transform = Transform3D(1, 0, 0, 0, 0.99999994, 0, 0, 0, 1, 0, 0, 0)
cast_shadow = 0
mesh = ExtResource("2_c5qep")
[node name="CameraSmooth" type="Node3D" parent="."]
transform = Transform3D(1, -0.00011616431, 0, 0.00011616433, 0.9999998, 0, 0, 0, 0.9999998, 0, 0, 0)
[node name="Camera3D" type="Camera3D" parent="CameraSmooth"]
transform = Transform3D(1, 0, 0, 0, 0.99999994, 0, 0, 0, 0.99999994, 0, 0, 0)
@@ -76,3 +279,20 @@ root_node = NodePath("../CameraSmooth/Camera3D")
libraries = {
&"": SubResource("AnimationLibrary_0hyrq")
}
[node name="AnimationTree" type="AnimationTree" parent="."]
root_node = NodePath("../CameraSmooth/Camera3D")
tree_root = ExtResource("3_r0h40")
anim_player = NodePath("../AnimationPlayer")
parameters/OnHit/active = false
parameters/OnHit/internal_active = false
parameters/OnHit/request = 0
parameters/OnJumpStart/active = false
parameters/OnJumpStart/internal_active = false
parameters/OnJumpStart/request = 0
parameters/OnJumpEnd/active = false
parameters/OnJumpEnd/internal_active = false
parameters/OnJumpEnd/request = 0
parameters/OnMantle/active = false
parameters/OnMantle/internal_active = false
parameters/OnMantle/request = 0

View File

@@ -28,6 +28,7 @@ public partial class WeaponSystem : RigidBody3D
private TweenQueueSystem _tweenQueueSystem;
private Transform3D _startTransform;
private Transform3D _startMeshTransform;
private Vector3 _throwDirection;
public Vector3 PlantLocation { get; set; }
@@ -36,7 +37,6 @@ public partial class WeaponSystem : RigidBody3D
public MeshInstance3D WeaponLocationIndicator { get; set; }
public StandardMaterial3D WeaponLocationIndicatorMaterial { get; set; }
public MeshInstance3D WeaponMesh { get; set; }
public StandardMaterial3D WeaponMaterial { get; set; }
public void Init(Node3D head, Camera3D camera)
{
@@ -53,13 +53,14 @@ public partial class WeaponSystem : RigidBody3D
WeaponLocationIndicatorMaterial = WeaponLocationIndicator.GetActiveMaterial(0) as StandardMaterial3D;
WeaponMesh = GetNode<MeshInstance3D>("Weapon");
WeaponMaterial = WeaponMesh.GetActiveMaterial(0) as StandardMaterial3D;
_startMeshTransform = WeaponMesh.Transform;
_tweenQueueSystem = GetNode<TweenQueueSystem>("TweenQueueSystem");
_tweenQueueSystem.Init(this);
_startTransform = Transform;
Freeze = true;
Visible = false;
BodyEntered += OnThrownWeaponReachesGround;
@@ -69,15 +70,15 @@ public partial class WeaponSystem : RigidBody3D
public void WeaponLeft()
{
WeaponLocationIndicator.Visible = true;
WeaponMaterial!.UseFovOverride = false;
Visible = true;
// WeaponLocationIndicator.Visible = true;
EmitSignalWeaponThrown();
}
public void WeaponBack()
{
WeaponLocationIndicator.Visible = false;
WeaponMaterial!.UseFovOverride = true;
Visible = false;
// WeaponLocationIndicator.Visible = false;
EmitSignalWeaponRetrieved();
}
@@ -87,14 +88,13 @@ public partial class WeaponSystem : RigidBody3D
Freeze = true;
GlobalPosition = location;
PlantLocation = location;
Visible = false;
}
public void ThrowWeapon(Vector3 end, bool hasHit, Vector3 collisionLocation, Vector3 collisionNormal)
{
_weaponState.SendEvent("throw");
WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 1f, 1f);
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 1f, 1f);
_throwDirection = (end - GlobalPosition).Normalized();
PlantLocation = collisionLocation;
@@ -118,10 +118,11 @@ public partial class WeaponSystem : RigidBody3D
{
_weaponState.SendEvent("plant");
WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
// WeaponLocationIndicatorMaterial.StencilColor = new Color(1f, 0.2f, 0.2f);
Freeze = true;
GlobalPosition = PlantLocation;
WeaponMesh.Transform = _startMeshTransform;
LookAt(GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
}
@@ -135,7 +136,7 @@ public partial class WeaponSystem : RigidBody3D
_weaponState.SendEvent("recover");
Transform = _startTransform;
Freeze = true;
Visible = true;
Visible = false;
}
public override void _IntegrateForces(PhysicsDirectBodyState3D state)
@@ -149,6 +150,14 @@ public partial class WeaponSystem : RigidBody3D
}
}
public override void _Process(double delta)
{
if (!FlyingState.Active) return;
WeaponMesh.Rotation = new Vector3(WeaponMesh.Rotation.X, WeaponMesh.Rotation.Y + (float) delta * 100, WeaponMesh.Rotation.Z);
//LookAt(GlobalTransform.Origin + LinearVelocity.Normalized(), Vector3.Up, false);
}
public bool IsPlantedUnderPlatform()
{
return PlantedState.Active && GlobalRotation.X > 1 && Math.Abs(GlobalRotation.Y) > 1;

View File

@@ -3,7 +3,7 @@
[ext_resource type="Script" uid="uid://iii3wfto4t5b" path="res://systems/weapon/WeaponSystem.cs" id="1_csqwk"]
[ext_resource type="PackedScene" uid="uid://dbe5f0p6lvqtr" path="res://systems/tween_queue/tween_queue_system.tscn" id="2_x1nha"]
[ext_resource type="Script" uid="uid://couw105c3bde4" path="res://addons/godot_state_charts/state_chart.gd" id="3_5owyf"]
[ext_resource type="CylinderMesh" uid="uid://b7vt0nk2htpo4" path="res://systems/weapon/weapon.tres" id="3_svc06"]
[ext_resource type="ArrayMesh" uid="uid://cho5fixitrbds" path="res://assets/swords/resources/sword23.tres" id="3_svc06"]
[ext_resource type="Script" uid="uid://jk2jm1g6q853" path="res://addons/godot_state_charts/compound_state.gd" id="4_svc06"]
[ext_resource type="Script" uid="uid://cytafq8i1y8qm" path="res://addons/godot_state_charts/atomic_state.gd" id="5_m0v1h"]
[ext_resource type="Script" uid="uid://cf1nsco3w0mf6" path="res://addons/godot_state_charts/transition.gd" id="6_jpdh0"]
@@ -51,7 +51,7 @@ transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0,
shape = SubResource("CylinderShape3D_avini")
[node name="Weapon" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0)
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0.8673003)
mesh = ExtResource("3_svc06")
[node name="StateChart" type="Node" parent="."]