TIL (71) | 2023.11.06 | Enemy Die Event

kjg5370·2023년 11월 6일
0

TIL

목록 보기
70/91
post-thumbnail

들어가기 앞서

오늘은 적이 죽을 때 실행해야 할 것들을 OnDie 라는 이벤트로 처리해서 적이 죽는 기능을 만들어보았습니다.

오늘 배운 것

  • Health 스크립트
    플레이어와 적이 공통적으로 사용하는 hp 스크립트입니다. 기본적인 체력을 설정하고 TakeDamage함수를 통해 데미지를 입은 만큼 체력을 줄입니다. 그리고 OnDie 이벤트를 선언하고 체력이 0이 되면 이벤트를 실행합니다.

    public class Health : MonoBehaviour
    {
        [SerializeField] protected int maxHealth = 100;
        public int health { get; private set; }
        public event Action OnDie;
    
        public bool IsDead => health == 0;
    
        protected virtual void Start()
        {
            health = maxHealth;
        }
    
        public virtual void TakeDamage(int damage)
        {
            if (health == 0) return;
            health = Mathf.Max(health - damage, 0);
    
            if (health == 0)
                OnDie?.Invoke();
        }
    }
  • Enemy의 스크립트와 연결
    Enemy 스크립트에 Health 가져와서 Health의 OnDie이벤트에 실행될 함수를 연결 시켜줍니다.

      public Health EnemyHealth { get; private set; 
    
      EnemyHealth = GetComponent<Health>();
    
      private void Start()
        {
            EnemyHealth.OnDie += OnDie;
        }
        void OnDie()
        {
            Controller.enabled = false;
            Animator.SetTrigger("Die");
            enabled = false;
        }

    이렇게 OnDie라는 함수를 Enemy에 만든다음 캐릭터의 HP가 0이 되면 실행되도록 연결합니다. 이렇게 되면 적의 HP가 0이 되면 컨트롤러를 비활성화 시키고 Die 트리거를 켜서 애니메이션을 실행한 후 적이 죽었으므로 Enemy스크립트를 비활성화해서 안움직이게 합니다.

  • TakeDamage
    플레이어의 총알에 Health의 TakeDamage를 통해 준 데미지 만큼 맞은 오브젝트의 HP를 감소시킵니다.

    • Bullet의 충돌 함수
       private void OnCollisionEnter(Collision collision)
        {
            if (collision.gameObject.tag != "Bullet")
            {
                if (collision.transform.TryGetComponent(out Health health))
                {
                    health.TakeDamage((int)damage);
                }
                gameObject.SetActive(false);
            }
        }

    TryGetComponent(out Health health)로 충돌한 오브젝트에서 Health 컴포넌트를 가져오려 시도하고, 해당 컴포넌트가 있는 경우 가져오고, 없으면 null을 반환합니다. Health 컴포넌트를 가져오는 데 성공하면 Health 컴포넌트의 TakeDamage 메서드를 호출하여 데미지를 입힙니다.


이렇게 총에 맞아서 죽는 모션이 잘 실행됩니다.

기억 할 것

  • 적이 죽었을 때 플레이어에게 다가오는 버그

    • 처음 적의 AI를 만들 때는 스테이트 스크립트 내의 Move()함수를 통해 적의 오브젝트를 움직였는데 나중에 내비메쉬를 추가하고 Move()함수를 쓰지 않아도 움직일 수 있게 되었고 Move함수에 필요한

      stateMachine.MovementSpeedModifier = 0f;

      MovementSpeedModifier를 0으로 해도 움직이는 현상을 발견했다.
      팀원들과 얘기하며 고민한 결과 내비메쉬와 Move()함수 적을 움직이는 기능이 두개가 있다는 것을 깨닫고 내비메쉬를 아래와 같이 비활성화 하여 문제를 해결하였다.

      NavMeshAgent.enabled = false;

진행 사항

  • 적의 무기에 takeDamage 함수 연결
    • 플레이어가 피격 시 hp 감소
  • 서 있는 상태로 움직이지 않고 총을 발사하는 스나이퍼 만들기
    • StandingSniper
      • Aiming Idle, Firing 애니메이션 추가
  • 적 총기 발사 시 이펙트, 사운드 연결
  • 적의 캐릭터 디자인 변경하여 여러개 만들어 놓기
    • 기존에 있던 Soldier05, 06, 07 프리팹 활용

내일 할 일

  • 불필요한 move함수 삭제
  • 피격 시 혈흔 효과
profile
학생입니다

0개의 댓글