금요일 오전에 완성됐지만 공격 기능이 구현됐지만
메인보드 고장 이슈로 지연됐다...
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만큼을 전달하여
데미지를 받는다.
'개발일지 > 최종프로젝트' 카테고리의 다른 글
241218(수) [Prefab 동적생성하기] (0) | 2024.12.18 |
---|---|
241217(화) [Fade In / Out] (0) | 2024.12.17 |
241211(수) [버그, 내일 할것] (0) | 2024.12.11 |
241210(화) [NPC 대화 업데이트] (1) | 2024.12.10 |
241209(월) [기술면접 메모] (0) | 2024.12.09 |