개발일지/최종프로젝트
241216(월) [공격 기능, 몬스터에게 데미지 주기]
게임 프로그래머
2024. 12. 16. 22:33
금요일 오전에 완성됐지만 공격 기능이 구현됐지만
메인보드 고장 이슈로 지연됐다...
protected virtual void AddInputActionsCallback()
{
PlayerController input = stateMachine.Player.input;
input.playerActions.Movement.canceled += OnMovementCanceld;
input.playerActions.Attack.performed += OnAttackPerformed;
input.playerActions.PickUp.performed += OnPickUpPerformed;
}
protected virtual void RemoveInputActionsCallback()
{
PlayerController input = stateMachine.Player.input;
input.playerActions.Movement.canceled -= OnMovementCanceld;
input.playerActions.Attack.canceled -= OnAttackCanceld;
input.playerActions.PickUp.canceled -= OnPickUpCanceld;
}
private void OnAttackPerformed(InputAction.CallbackContext context)
{
stateMachine.Player.Animator.SetTrigger(stateMachine.Player.AnimationData.AttackParameterHash);
stateMachine.changeState(stateMachine.AttackState);
}
private void OnAttackCanceld(InputAction.CallbackContext context)
{
}
basestate에서 트리거를 통해 공격 애니메이션 전환
basestate를 상속받는 attackstate를 만들고
코드전문
더보기
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.PlayerLoop;
public class PlayerAttackState : PlayerBaseState
{
private bool isAttacking;
public PlayerAttackState(PlayerStateMachine stateMachine) : base(stateMachine)
{
}
public override void Enter()
{
base.Enter();
isAttacking = true;
stateMachine.Player.StartCoroutine(AttackTime());
}
public override void Exit()
{
base.Exit();
isAttacking = false;
}
public override void Update()
{
base.Update();
if (!isAttacking)
{
stateMachine.changeState(stateMachine.IdleState);
}
}
private void OnAttack()
{
Collider2D[] hitEnemy = Physics2D.OverlapCircleAll(stateMachine.Player.transform.position,
stateMachine.Player.PlayerSOData.AttackData.AttackRange);
foreach (Collider2D enemy in hitEnemy)
{
Bug bug = enemy.GetComponent<Bug>();
if (bug != null)
{
bug.TakeDamage(stateMachine.Player.PlayerSOData.AttackData.AttackDamage);
}
}
}
private IEnumerator AttackTime()
{
OnAttack();
yield return new WaitForSeconds(stateMachine.Player.PlayerSOData.AttackData.AttackDuration);
isAttacking = false;
yield return new WaitForSeconds(stateMachine.Player.PlayerSOData.AttackData.AttackCooltime);
stateMachine.changeState(stateMachine.IdleState);
}
}
진입시 코루틴을 이용하여 AttackTime을 실행한다.
private IEnumerator AttackTime()
{
OnAttack();
yield return new WaitForSeconds(stateMachine.Player.PlayerSOData.AttackData.AttackDuration);
isAttacking = false;
yield return new WaitForSeconds(stateMachine.Player.PlayerSOData.AttackData.AttackCooltime);
stateMachine.changeState(stateMachine.IdleState);
}
공격 실행후 duration만큼 애니메이션이 실행되고
AttackCooltime만큼 공격이 대기시간이 생긴다.
private void OnAttack()
{
Collider2D[] hitEnemy = Physics2D.OverlapCircleAll(stateMachine.Player.transform.position,
stateMachine.Player.PlayerSOData.AttackData.AttackRange);
foreach (Collider2D enemy in hitEnemy)
{
Bug bug = enemy.GetComponent<Bug>();
if (bug != null)
{
bug.TakeDamage(stateMachine.Player.PlayerSOData.AttackData.AttackDamage);
}
}
}
OverlapCircleAll을 이용하여 플레이어 위치에서
AttackRange 만큼의 충돌체를 감지한다.
반복문을 통해 bug 컴포넌트를 찾은뒤
bug의 takedamage 함수를 호출하여 attackdamage를 매개변수로 전달한다.
public void TakeDamage(float damage)
{
bugStats.currentHealth -= damage;
Debug.Log($"{bugStats.name}가 {damage}의 데미지를 받았습니다. 현재 체력: {bugStats.currentHealth}");
if (bugStats.currentHealth <= 0)
{
Destroy(gameObject);
Debug.Log("Die");
}
}
[bug] 스크립트내에 있는 TakeDamage 함수
스크립터블 오브젝트에 있는 bugstats에 currentHealth에 매개변수 damage만큼을 전달하여
데미지를 받는다.