diff --git a/systems/head/HeadSystem.cs b/systems/head/HeadSystem.cs index 096c2c1c..f621e188 100644 --- a/systems/head/HeadSystem.cs +++ b/systems/head/HeadSystem.cs @@ -63,7 +63,8 @@ public partial class HeadSystem : Node3D [ExportGroup("First Person rig")] private Node3D _fpRig; - private Vector3 _fpRigInitialPosition; + 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")] @@ -72,6 +73,14 @@ public partial class HeadSystem : Node3D 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() { @@ -81,7 +90,8 @@ public partial class HeadSystem : Node3D _animationPlayer = GetNode("AnimationPlayer"); _fpRig = GetNode("FPRig"); - _fpRigInitialPosition = _fpRig.GlobalPosition; + _fpDisplacedRig = GetNode("FPRig/Sword"); + _fpDisplacedRigInitialRotation = _fpDisplacedRig.Rotation; _slidingNoise.NoiseType = FastNoiseLite.NoiseTypeEnum.Perlin; _slidingNoise.SetFrequency(SlidingJitterFrequency); @@ -167,16 +177,41 @@ public partial class HeadSystem : Node3D _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; - // var lookInputLerped = lookDir.Lerp(Vector2.Zero, (float) delta * WeaponAdjustmentSpeed); + // 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); @@ -200,6 +235,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; diff --git a/systems/head/head_system.tscn b/systems/head/head_system.tscn index d9bbbde1..aebf76c4 100644 --- a/systems/head/head_system.tscn +++ b/systems/head/head_system.tscn @@ -62,13 +62,17 @@ _data = { [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.4349438, 0.02783122, -0.90002745, 0.18060648, 0.97651464, 0.1174756, 0.8821594, -0.21364608, 0.41970247, 0.53640664, -0.82246387, -1.9288678) [node name="SwordMesh" type="MeshInstance3D" parent="FPRig/Sword"] -transform = Transform3D(0.43494374, 0.027831191, -0.9000275, 0.1806065, 0.9765146, 0.117475554, 0.8821594, -0.2136461, 0.41970232, 0.53640664, -0.82246387, -1.9288678) +transform = Transform3D(1, 0, 0, 0, 0.99999994, 0, 0, 0, 1, 0, 0, 0) cast_shadow = 0 mesh = ExtResource("2_c5qep")