149 lines
4.2 KiB
C#
149 lines
4.2 KiB
C#
|
using UnityEngine;
|
||
|
using UnityEngine.InputSystem;
|
||
|
|
||
|
public enum AttackState : byte
|
||
|
{
|
||
|
Idle = 0,
|
||
|
Light,
|
||
|
Medium,
|
||
|
Heavy
|
||
|
}
|
||
|
|
||
|
[RequireComponent(typeof(Rigidbody2D), typeof(Animator), typeof(InputBase))]
|
||
|
public class Player : MonoBehaviour
|
||
|
{
|
||
|
// Will want to create an "Input Actions" asset, this should allow the user to set their bindings in a menu and I'll be able to load that during the game.
|
||
|
// The above is super important for this prototype, but could be used for all other prototypes.
|
||
|
public float speed;
|
||
|
public float jumpForce;
|
||
|
public HitBox bodyHitBox;
|
||
|
public HitBox lightHitBox;
|
||
|
public HitBox mediumHitBox;
|
||
|
public HitBox heavyHitBox;
|
||
|
public float maxHealth;
|
||
|
|
||
|
private Rigidbody2D _rigidbody;
|
||
|
private bool _isGrounded;
|
||
|
private Vector2 _verticalVelocity;
|
||
|
private Animator _animator;
|
||
|
private AttackState _currentAttack;
|
||
|
private int _currentAnimationStateIndex;
|
||
|
private InputBase _input;
|
||
|
private float _health;
|
||
|
private float _hitStunStartTime;
|
||
|
private float _hitStunDuration;
|
||
|
private bool _isHitStun;
|
||
|
|
||
|
private const string CurrentAttackText = "CurrentAttack";
|
||
|
private bool IsAttacking => _currentAttack != AttackState.Idle;
|
||
|
|
||
|
private void Start()
|
||
|
{
|
||
|
_health = maxHealth;
|
||
|
_rigidbody = GetComponent<Rigidbody2D>();
|
||
|
_animator = GetComponent<Animator>();
|
||
|
_input = GetComponent<InputBase>();
|
||
|
_input.AttackCallback = ChangeAttackingState;
|
||
|
|
||
|
_rigidbody.gravityScale = 0;
|
||
|
|
||
|
if (_animator.parameterCount < 1)
|
||
|
{
|
||
|
Debug.LogAssertion("Animator needs to have one property named \"CurrentState\"");
|
||
|
}
|
||
|
|
||
|
foreach (var parameter in _animator.parameters)
|
||
|
{
|
||
|
if (parameter.name == CurrentAttackText)
|
||
|
{
|
||
|
_currentAnimationStateIndex = parameter.nameHash;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bodyHitBox.DamageAmount = 0;
|
||
|
bodyHitBox.DoesDealDamage = false;
|
||
|
|
||
|
bodyHitBox.TakeDamage += DealDamage;
|
||
|
lightHitBox.TakeDamage += DealDamage;
|
||
|
mediumHitBox.TakeDamage += DealDamage;
|
||
|
heavyHitBox.TakeDamage += DealDamage;
|
||
|
}
|
||
|
|
||
|
private void DealDamage(float damage, float hitStunDuration)
|
||
|
{
|
||
|
_health -= damage;
|
||
|
_hitStunDuration = hitStunDuration;
|
||
|
_hitStunStartTime = Time.time;
|
||
|
_isHitStun = true;
|
||
|
_animator.SetBool("IsHitStun", _isHitStun);
|
||
|
if (_health <= 0)
|
||
|
{
|
||
|
Debug.Log("You are dead!");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public float HealthPercent() => _health / maxHealth;
|
||
|
|
||
|
public void StopAttack()
|
||
|
{
|
||
|
_currentAttack = AttackState.Idle;
|
||
|
}
|
||
|
|
||
|
private void ChangeAttackingState(AttackState state)
|
||
|
{
|
||
|
_currentAttack = state;
|
||
|
}
|
||
|
|
||
|
private void JumpPerform(InputAction.CallbackContext callbackContext)
|
||
|
{
|
||
|
if (_isGrounded)
|
||
|
{
|
||
|
_verticalVelocity.y = jumpForce;
|
||
|
_verticalVelocity.x = _input.GetMovementDirection() * speed;
|
||
|
_isGrounded = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void Update()
|
||
|
{
|
||
|
if (_isGrounded)
|
||
|
{
|
||
|
if (Time.time >= _hitStunStartTime + _hitStunDuration)
|
||
|
{
|
||
|
_isHitStun = false;
|
||
|
_animator.SetBool("IsHitStun", _isHitStun);
|
||
|
}
|
||
|
|
||
|
if (!IsAttacking && !_isHitStun)
|
||
|
{
|
||
|
var dir = _input.GetMovementDirection();
|
||
|
var pos = _rigidbody.position;
|
||
|
pos.x += dir * speed * Time.deltaTime;
|
||
|
_rigidbody.position = pos;
|
||
|
}
|
||
|
|
||
|
_animator.SetInteger(_currentAnimationStateIndex, (int)_currentAttack);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var pos = _rigidbody.position;
|
||
|
pos += _verticalVelocity * Time.deltaTime;
|
||
|
_rigidbody.position = pos;
|
||
|
_verticalVelocity += Physics2D.gravity * Time.deltaTime;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnCollisionEnter2D(Collision2D other)
|
||
|
{
|
||
|
foreach (var contact in other.contacts)
|
||
|
{
|
||
|
// Depending how crouch is implemented this might break or be fickle.
|
||
|
if (contact.point.y < _rigidbody.transform.position.y)
|
||
|
{
|
||
|
_isGrounded = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|