proto_fighter/Assets/Scripts/Player.cs

149 lines
4.2 KiB
C#
Raw Permalink Normal View History

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;
}
}
}
}