basic aim assist system
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 / Test (push) Successful in 7m42s
Create tag and build when new code gets to main / Export (push) Successful in 10m3s

This commit is contained in:
2026-02-08 20:34:54 +01:00
parent c4be97e0de
commit 3148d3b69b
8 changed files with 91 additions and 0 deletions

View File

@@ -81,6 +81,14 @@ public partial class PlayerController : CharacterBody3D,
// Combat stuff
[ExportCategory("Combat")]
[ExportGroup("General")]
[Export(PropertyHint.Range, "0,1f,0.01,or_greater")]
public float AimAssistStrength { get; set; } = 0.1f;
[Export(PropertyHint.Range, "0,1f,0.1,or_greater")]
public float AimAssistReductionWhenCloseToTarget { get; set; } = 0.3f;
[Export(PropertyHint.Range, "0,10f,0.1,or_greater")]
public float AimAssistReductionStartDistance { get; set; } = 10f;
[ExportGroup("Damage")]
[Export] public RDamage RDamage { get; set; }
[Export] public RKnockback RKnockback { get; set; }
@@ -372,6 +380,7 @@ public partial class PlayerController : CharacterBody3D,
private readonly List<IDamageable> _hitEnemies = new List<IDamageable>();
private ShapeCast3D _closeEnemyDetector;
private RayCast3D _aimAssisRayCast;
private Camera3D _camera;
public override void _Ready()
@@ -386,6 +395,8 @@ public partial class PlayerController : CharacterBody3D,
PlayerUi = GetNode<PlayerUi>("UI");
_closeEnemyDetector = GetNode<ShapeCast3D>("%CloseEnemyDetector");
_closeEnemyDetector.TargetPosition = _closeEnemyDetector.TargetPosition.Normalized() * TargetingDistance;
_aimAssisRayCast = GetNode<RayCast3D>("AimAssistRayCast");
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
// DashIndicator = GetNode<TextureRect>("%DashIndicator");
PowerCooldownIndicator = GetNode<ColorRect>("%DashCooldownIndicator");
@@ -939,6 +950,31 @@ public partial class PlayerController : CharacterBody3D,
public float CalculateGravityForce() => _gravity * Weight;
// Camera stuff
private Vector2 ComputeAimAssist()
{
_aimAssisRayCast.SetRotation(HeadSystem.GetGlobalLookRotation());
if (!_aimAssisRayCast.IsColliding()) return Vector2.Zero;
// Hard dependency on the aim assist to be an Area3D and having a parent
var collidedObject = _aimAssisRayCast.GetCollider() as Area3D;
if (collidedObject is null) return Vector2.Zero;
if (collidedObject.GetParent() is not ITargetable targetable) return Vector2.Zero;
var targetPosition = targetable.GetTargetGlobalPosition();
var targetPositionOnCamera = _camera.UnprojectPosition(targetPosition);
var centerOfScreen = _camera.GetViewport().GetVisibleRect().Size / 2f;
var aimAssistDirection = centerOfScreen - targetPositionOnCamera;
var aimAssist = aimAssistDirection * AimAssistStrength / 1000f;
var distanceToTarget = (targetPosition - HeadSystem.GlobalPosition).Length();
if (distanceToTarget > AimAssistReductionStartDistance) return aimAssist; // useless but clearer
// Reduce aim assist when closing in on target because it can mess with the camera when dashing through
var distanceFactor = Mathf.Clamp(distanceToTarget / AimAssistReductionStartDistance, 0f, 1f);
var aimAssistReductionFactor = Mathf.Lerp(AimAssistReductionWhenCloseToTarget, 1f, distanceFactor);
return aimAssist * aimAssistReductionFactor;
}
private void LookAround(double delta)
{
Vector2 inputLookDir = new Vector2(_inputRotateY, _inputRotateFloorplane);
@@ -947,6 +983,9 @@ public partial class PlayerController : CharacterBody3D,
var wallHugContactPoint = _onWallRunning.Active ? _currentWallContactPoint : Vector3.Zero;
var moveInput = GetGlobalMoveInput();
if (_isUsingGamepad)
inputLookDir += ComputeAimAssist();
var lookAroundInputs = new HeadSystem.CameraParameters(
Delta: delta,
LookDir: inputLookDir,
@@ -1772,6 +1811,9 @@ public partial class PlayerController : CharacterBody3D,
// DashIndicatorMesh.Visible = true;
if (!isOnFloorCustom())
ReduceTimeScaleWhileAiming();
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() *
(DashSystem.DashCast3D.TargetPosition.Length() + DashSystem.DashCastRadius);
}
public void HandleAiming(float delta)
{
@@ -1785,6 +1827,8 @@ public partial class PlayerController : CharacterBody3D,
{
DashSystem.StopPreparingDash();
_aimAssisRayCast.TargetPosition = _aimAssisRayCast.TargetPosition.Normalized() * (TargetingDistance*1.5f);
// DashIndicatorMesh.Visible = false;
}