feat: Player Dash & DoubleJump

This commit is contained in:
2026-06-09 14:01:18 +02:00
parent 1e9e4ace81
commit 8698d55b9f
10 changed files with 11190 additions and 238 deletions

View File

@@ -1,8 +1,10 @@
using System.Collections;
using TMPro.EditorUtilities;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using static Player;
using static UnityEditor.Experimental.GraphView.GraphView;
public class Player : MonoBehaviour
@@ -15,6 +17,7 @@ public class Player : MonoBehaviour
Moving,
Jumping,
Falling,
Dashing,
Stunned,
Dead,
Loser,
@@ -37,6 +40,26 @@ public class Player : MonoBehaviour
public float StickedGravity = -5;
}
[System.Serializable]
public class Dash
{
[Tooltip("Can the player dash?")]
public bool CanDash = true;
public float DashDuration = .3f;
public float DashDelay = 1.5f;
public float DashForce = 50;
}
[System.Serializable]
public class DoubleJump
{
[Tooltip("Can the player duble jump?")]
public bool CanDoubleJump = true;
}
[System.Serializable]
public class Settings
{
@@ -76,23 +99,21 @@ public class Player : MonoBehaviour
[Header("Features")]
public WallRun WallRun;
public Dash Dash;
public DoubleJump DoubleJump;
}
[System.Serializable]
public class References
{
public CharacterController Controller;
public InputActionAsset InputActions;
public CharacterController Controller;
public GameObject COG;
public GameObject DiePrefab;
public ParticleSystem[] DashEffects;
public Transform[] DashJointsLevel;
}
/*[System.Serializable]
public class Events
{
public UnityEvent OnLose;
public UnityEvent OnDie;
}*/
[System.Serializable]
public class StateContainer
{
@@ -105,6 +126,9 @@ public class Player : MonoBehaviour
[Tooltip("Is player sticked to wall?")]
public bool IsStickedToWall;
[Tooltip("Is player dashing?")]
public bool IsDashing = false;
[Tooltip("Can player stick to walls?")]
public bool CanStickToWalls;
@@ -120,6 +144,9 @@ public class Player : MonoBehaviour
[Tooltip("Elapsed time since sticked to wall")]
[Range(-1, 1)] public float StickedTime;
[Tooltip("Elapsed time since dash")]
[Range(-1, 1)] public float DashingTime;
[Tooltip("Current velocity in m/s")]
public Vector3 Velocity;
@@ -133,7 +160,6 @@ public class Player : MonoBehaviour
[SerializeField] private Settings _settings;
[SerializeField] private References _references;
//[SerializeField] private Events _events;
[SerializeField, ReadOnly] private StateContainer _state;
public StateContainer State => _state;
@@ -185,6 +211,8 @@ public class Player : MonoBehaviour
private InputAction _moveAction;
private InputAction _runAction;
private InputAction _jumpAction;
private InputAction _targetAction;
private InputAction _dashAction;
// Camera
private Camera _camera;
@@ -200,6 +228,11 @@ public class Player : MonoBehaviour
private Vector3 _lastPlatformPosition;
private Quaternion _lastPlatformRotation;
private Vector3 _platformVelocity;
// Double Jump
private bool _doubleJump;
private float _doubleJumpTime;
#endregion
#region Unity Lifecycle
@@ -219,6 +252,8 @@ public class Player : MonoBehaviour
_moveAction = _references.InputActions.FindActionMap("Player").FindAction("Move");
_runAction = _references.InputActions.FindActionMap("Player").FindAction("Sprint");
_jumpAction = _references.InputActions.FindActionMap("Player").FindAction("Jump");
_targetAction = _references.InputActions.FindActionMap("Player").FindAction("Target");
_dashAction = _references.InputActions.FindActionMap("Player").FindAction("Attack");
// Camera
_camera = Camera.main;
@@ -235,6 +270,8 @@ public class Player : MonoBehaviour
_moveAction?.Enable();
_runAction?.Enable();
_jumpAction?.Enable();
_targetAction?.Enable();
_dashAction?.Enable();
}
void OnDisable()
@@ -242,6 +279,8 @@ public class Player : MonoBehaviour
_moveAction?.Disable();
_runAction?.Disable();
_jumpAction?.Disable();
_targetAction?.Disable();
_dashAction?.Disable();
}
void Update()
@@ -252,6 +291,7 @@ public class Player : MonoBehaviour
SetGravity(t);
SetVelocity(t);
SetJump();
SetDash();
SetMovement(t);
SetState();
}
@@ -281,6 +321,13 @@ public class Player : MonoBehaviour
bool wasGrounded = _state.IsGrounded;
bool isGrounded = rayHit || sphereHit;
// Double Jump
if (isGrounded)
{
_doubleJump = false;
_doubleJumpTime = 0;
}
// Wall run
if (_settings.WallRun.CanRunOnWalls && !_state.CanStickToWalls)
{
@@ -389,7 +436,7 @@ public class Player : MonoBehaviour
// Reset platform velocity
_platformVelocity = Vector3.zero;
_state.FallingTime = 0; ;
_state.FallingTime = 0;
}
else
{
@@ -447,6 +494,7 @@ public class Player : MonoBehaviour
case PlayerState.Loser:
case PlayerState.Dead:
allowInput = false;
_state.Running = 0;
break;
}
@@ -492,19 +540,66 @@ public class Player : MonoBehaviour
private void SetJump()
{
if (_jumpAction.triggered && (_state.IsGrounded || _state.IsStickedToWall))
if (_state.IsPaused)
return;
if (_jumpAction.triggered && (_state.IsGrounded || _state.IsStickedToWall || (!_doubleJump && _settings.DoubleJump.CanDoubleJump)))
{
if (_state.IsStickedToWall)
{
_state.Velocity = Vector3.Lerp(_wallNormal, Vector3.up, .4f).normalized * _settings.JumpForce * 1.6f;
_doubleJump = false;
_doubleJumpTime = 0;
}
else
{
_state.Velocity.y = _settings.JumpForce;
if (!_doubleJump)
_doubleJump = true;
}
_state.Ground = null;
_state.IsStickedToWall = false;
_state.CanStickToWalls = false;
_groundCheckRadius = _references.Controller.radius + _settings.GroundTolerance;
}
if (_doubleJump)
{
_doubleJumpTime += Time.deltaTime;
}
}
private void SetDash()
{
if (!_settings.Dash.CanDash || _state.IsPaused)
return;
_state.DashingTime = Mathf.Clamp(_state.DashingTime + Time.deltaTime, 0, _settings.Dash.DashDelay);
float dashLoad = Mathf.Pow(Mathf.Clamp01((_state.DashingTime - _settings.Dash.DashDuration) / (_settings.Dash.DashDelay - _settings.Dash.DashDuration)), 2);
foreach (Transform jnt in _references.DashJointsLevel)
jnt.localScale = new Vector3(1, dashLoad, 1);
if (!_state.IsDashing)
{
if (_dashAction.triggered && !_targetAction.IsPressed() && _state.DashingTime == _settings.Dash.DashDelay && !_state.IsStickedToWall)
{
_state.Velocity += transform.forward * _settings.Dash.DashForce;
_state.IsDashing = true;
_state.DashingTime = 0;
foreach(ParticleSystem p in _references.DashEffects)
p.Play();
}
}
else if(_state.DashingTime >= _settings.Dash.DashDuration)
{
_state.IsDashing = false;
}
}
private void SetMovement(float deltaTime)
@@ -521,23 +616,26 @@ public class Player : MonoBehaviour
_references.Controller.Move(motion * deltaTime);
// Rotate Player
if (_state.HorizontalVelocity.sqrMagnitude > .001f)
if (_state.HorizontalVelocity.magnitude > .01f)
{
Vector3 velocity = _state.HorizontalVelocity;
if (_state.Running > 0)
{
velocity = Vector3.Lerp(velocity, Vector3.down, _state.Running * .4f).normalized;
}
Quaternion targetRot = Quaternion.LookRotation(velocity, Vector3.up);
Quaternion controlerRot = Quaternion.LookRotation(velocity, Vector3.up);
if (_state.IsStickedToWall)
targetRot = Quaternion.LookRotation(_wallDirection);
controlerRot = Quaternion.LookRotation(_wallDirection);
float t = _settings.RotationSpeed * deltaTime;
targetRot = Quaternion.Slerp(transform.rotation, targetRot, t);
controlerRot = Quaternion.Slerp(transform.rotation, controlerRot, t);
transform.rotation = targetRot;
transform.rotation = controlerRot;
}
// Rotate COG
float angle = Mathf.Lerp(0, 5, _state.Running);
if (_doubleJump)
angle = Mathf.Clamp01(_doubleJumpTime * 3) * 360;
_references.COG.transform.localRotation = Quaternion.Euler(angle, 0, 0);
}
private void SetState()
@@ -549,7 +647,11 @@ public class Player : MonoBehaviour
return;
}
if (State.IsGrounded || State.IsStickedToWall)
if (_state.IsDashing)
{
State.CurrentState = PlayerState.Dashing;
}
else if (State.IsGrounded || State.IsStickedToWall)
{
if (State.HorizontalVelocity.sqrMagnitude > .1f)
{
@@ -571,22 +673,7 @@ public class Player : MonoBehaviour
State.CurrentState = PlayerState.Falling;
}
}
//TriggerStateEvents();
}
/*private void TriggerStateEvents()
{
switch (_state.CurrentState)
{
case PlayerState.Loser:
_events.OnLose?.Invoke();
break;
case PlayerState.Dead:
_events.OnDie?.Invoke();
break;
}
}*/
#endregion
}

View File

@@ -45,9 +45,10 @@ public class PlayerAnimation : MonoBehaviour
private void Init()
{
_stateMapper = new PlayerAnimationStateMapper[8];
_stateMapper = new PlayerAnimationStateMapper[9];
int i = 0;
_stateMapper[0] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Idle,
AnimatorState = "move",
@@ -55,7 +56,7 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_move",
};
_stateMapper[1] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Moving,
AnimatorState = "move",
@@ -63,7 +64,7 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_move",
};
_stateMapper[2] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Jumping,
AnimatorState = "jump",
@@ -71,7 +72,15 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_jump",
};
_stateMapper[3] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Dashing,
AnimatorState = "dash",
BlockingState = "",
Trigger = "trigger_dash",
};
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Falling,
AnimatorState = "fall",
@@ -79,7 +88,7 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_fall",
};
_stateMapper[4] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Stunned,
AnimatorState = "stun",
@@ -87,7 +96,7 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_stun",
};
_stateMapper[5] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Dead,
AnimatorState = "eliminate",
@@ -95,7 +104,7 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_eliminate",
};
_stateMapper[6] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Loser,
AnimatorState = "lose",
@@ -103,7 +112,7 @@ public class PlayerAnimation : MonoBehaviour
Trigger = "trigger_lose",
};
_stateMapper[7] = new PlayerAnimationStateMapper()
_stateMapper[i++] = new PlayerAnimationStateMapper()
{
PlayerState = Player.PlayerState.Winner,
AnimatorState = "win",