내일배움캠프 57일차 TIL : 애니메이션과 타격시점 맞추기

woollim·2024년 12월 12일
0

내일배움캠프TIL

목록 보기
50/65
post-thumbnail

■ 개요

○ 오늘 계획

  • 근접 몬스터
    • Melee2 애니메이터, 스테이트 제작
    • 플레이어 콜라이더 충돌시에만 딜이 들어가도록
      • 이벤트 함수 수정
      • 손에 콜라이더 달기
  • 원거리 몬스터
    • 스테이트 수정
    • 화살에 충돌시에만 공격당하게
  • 스테이지 클리어, 실패 구현


■ 애니메이션과 타격시점 맞추기

○ 사담

  • 근접 몬스터 작업 중 손으로 타격하는 순간에만 플레이어에게 딜이 들어가도록 하고싶었다. 그리고 재활용 가능한 템플릿이길 바랬다.
  • 이게 옳은 방법인지는 모르겠으나 다른 작업물을 참고하는것 말고 직접 만들어 보고 싶어서(재밌었다😁) 고민끝에 나온 결과물이다.
  • 내일 코드 안정성 점검할때 다시한번 고찰해볼 예정이다.

○ 코드

  • Enemy에서 Weapon 클래스 초기화, currentTarget 변수 추가
public class Enemy : MonoBehaviour, IPoolable, IDamageable
{
    public GameObject currentTarget = null;
    public MeleeEnemyWeapon Weapon { get; private set; }
    protected virtual void Awake()
    {
    	Weapon = GetComponentInChildren<MeleeEnemyWeapon>();
		if(Weapon != null )
    		Weapon.MasterInit(this);
  • MeleeEnemy의 MeleeAttack()함수 - 실제 데미지를 가하는 함수
public class MeleeEnemy : Enemy
{
    public void MeleeAttack()
    {
        if (currentTarget)
        {
            Managers.Character.Player.stat.TakeDamage(Stat.AD);
        }
    }
}
  • MeleeEnemyWeapon 클래스 - 몬스터가 들고있는 무기에 부착하는 클래스
using UnityEngine;

public class MeleeEnemyWeapon : MonoBehaviour
{
    private Enemy master;

    public void MasterInit(Enemy enemy)
    {
        master = enemy;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject == Managers.Character.Player.gameObject)
        {
            master.currentTarget = other.gameObject;
        }
        else
        {
            master.currentTarget = null;
        }
    }
}
  • 공격 스테이트 스크립트 일부
public override void Enter()
{
    base.Enter();

    StartAnimation(stateMachine.Enemy.AnimationData.AttackParameterHash);
    StartAnimation(stateMachine.Enemy.AnimationData.Attack2ParameterHash);

    stateMachine.Enemy.Agent.isStopped = true;
    stateMachine.Enemy.currentTarget = null;

    stateMachine.Enemy.StartCoroutine(WaitForAnimationToEnd());
}

public override void Exit()
{
    base.Exit();

    StopAnimation(stateMachine.Enemy.AnimationData.AttackParameterHash);
    StopAnimation(stateMachine.Enemy.AnimationData.Attack2ParameterHash);

    stateMachine.Enemy.Agent.isStopped = false;
    stateMachine.Enemy.currentTarget = null;
}

/// <summary>
/// attack2 애니메이션의 실행이 끝날때까지 대기하는 코루틴 입니다. 끝나면 attack1으로 스테이트를 전환합니다.
/// </summary>
public IEnumerator WaitForAnimationToEnd()
{
    do
    {
        currentInfo = stateMachine.Enemy.Animator.GetCurrentAnimatorStateInfo(0);

        yield return null;
    } while (currentInfo.IsTag(tag) && currentInfo.normalizedTime < 1);

    stateMachine.LastAttackTime = Time.time;
    stateMachine.ChangeState(stateMachine.Attack1State);
}
  • 타격 시점 애니메이션 클립에 이벤트 추가




○ 동작 설명

  1. 몬스터가 들고있는 무기에는 콜라이더와 MeleeEnemyWeapon클래스가 부착되어있음. 충돌한 오브젝트가 플레이어일때만 enemy의 타겟변수에 플레이어 오브젝트를 저장함.
  2. 공격 스테이트로 변환시 stateMachine.Enemy.currentTarget = null; 코드로 타겟 변수를 비워둠.
  3. 그 이후 공격 애니메이션이 재생되고, 손으로 타격하는 애니메이션이 재생되며 손(무기)와 플레이어가 충돌한다. MeleeEnemyWeapon클래스 내부의 트리거에 의하여 타겟 변수에 플레이어가 담기고, 애니메이션 클립의 이벤트가 발생함
  4. MeleeAttack()이 호출되며 플레이어에게 데미지를 가함

○ 의도

  • 앞으로 다른 종류의 몬스터를 만들어도 재활용할 수 있게끔(무기 스크립트) 만듬

0개의 댓글