좀비 AI 기능을 구현하는 좀비 스크립트는 다음과 가능 기능을 구현해야 합니다.

LivingEntity에서 제공하는 기본 생명기능

외부에서 초기 능력치 초기화 가능

주기적으로 목표 위치를 찾아 경로갱신

피탄받았을때 효과 재생

트리거 콜라이더를 이용 감지된 적을 공격

사망시 추적 중지

사망시 사망효과 재생

 

  1. 좀비 필드
  2. public LayerMask whatIsTarget; // 추적 대상 레이어
  3. private NavMeshAgent navMeshAgent; // 경로계산 AI 에이전트
  4. public ParticleSystem hitEffect; // 피격시 재생할 파티클 효과
     public AudioClip deathSound; // 사망시 재생할 소리
     public AudioClip hitSound; // 피격시 재생할 소리
  5.     private Animator zombieAnimator; // 애니메이터 컴포넌트, 여기서는 사용안함
        private AudioSource zombieAudioPlayer; // 오디오 소스 컴포넌트, 효과음 재생을 위
        private Renderer zombieRenderer; // 렌더러 컴포넌트, 좀비 색을 변경시 사용
  6.     public float damage = 20f; // 공격력
        public float timeBetAttack = 0.5f; // 공격 간격
        private float lastAttackTime; // 마지막 공격 시점
  7. 추적할 대상이 존재하는지 알려주는 프로퍼티, targetEntity이고 죽지 않을 겨우만 true이므로 생명체를 체크할수 있음
// 추적할 대상이 존재하는지 알려주는 프로퍼티
private bool hasTarget  {
    get {
        // 추적할 대상이 존재하고, 대상이 사망하지 않았다면 true
        if (targetEntity != null && !targetEntity.dead)  {
            return true;
        }     
        return false; // 그렇지 않다면 false
    }
}

private void Awake() {}  사용할 컴포넌트들을 연결합니다.

public void Setup(ZombieData zombieData) {} 좀비의 능력치를 초기화 합니다.

private void Start( UpdatePath() ;) {  // 게임 오브젝트 활성화와 동시에 AI의 추적 루틴 시작 }

private void Update() {    // 추적 대상의 존재 여부에 따라 다른 애니메이션을 재생 }

private IEnumerator UpdatePath() { // 주기적으로 추적할 대상의 위치를 찾아 경로를 갱신 }

타겟도 이동중이므로 타겟이 존재한다면 타겟의 위치를 갱신한다.

                // 추적 대상 존재 : 경로를 갱신하고 AI 이동을 계속 진행
                navMeshAgent.isStopped = false;
                navMeshAgent.SetDestination(targetEntity.transform.position);

private IEnumerator UpdatePath() {
    // 살아있는 동안 무한 루프
    while (!dead)
    {
        if (hasTarget)
        {
            // 추적 대상 존재 : 경로를 갱신하고 AI 이동을 계속 진행
            navMeshAgent.isStopped = false;
            navMeshAgent.SetDestination(
                targetEntity.transform.position);
        }
        else
        {
            // 추적 대상 없음 : AI 이동 중지
            navMeshAgent.isStopped = true;

            // 20 유닛의 반지름을 가진 가상의 구를 그렸을때, 구와 겹치는 모든 콜라이더를 가져옴
            // 단, whatIsTarget 레이어를 가진 콜라이더만 가져오도록 필터링
            Collider[] colliders =
                Physics.OverlapSphere(transform.position, 20f, whatIsTarget);

            // 모든 콜라이더들을 순회하면서, 살아있는 LivingEntity 찾기
            for (int i = 0; i < colliders.Length; i++)
            {
                // 콜라이더로부터 LivingEntity 컴포넌트 가져오기
                LivingEntity livingEntity = colliders[i].GetComponent<LivingEntity>();

                // LivingEntity 컴포넌트가 존재하며, 해당 LivingEntity가 살아있다면,
                if (livingEntity != null && !livingEntity.dead)
                {
                    // 추적 대상을 해당 LivingEntity로 설정
                    targetEntity = livingEntity;

                    // for문 루프 즉시 정지
                    break;
                }
            }
        }

        // 0.25초 주기로 처리 반복
        yield return new WaitForSeconds(0.25f);
    }
}

public override void OnDamage(float damage, }  // 데미지를 입었을때 실행할 처리

public override void Die() { // LivingEntity의 Die()를 실행하여 기본 사망 처리 실행}

private void OnTriggerStay(Collider other) {
        // 자신이 사망하지 않았으며,
        // 최근 공격 시점에서 timeBetAttack 이상 시간이 지났다면 공격 가능 }

Player를 선택하고Layer를 PLAYER로 바꿉니다. 모든 child에 적용할거냐는 질문에 No 합니다.


  Player를 Prefabs 폴더로 끌어다 프리팹으로 만듭니다. 

하이라키뷰에서 Enemy를 선택하고 public을 연결해줍니다.

 

Zombie.cs
0.01MB
Zombie Data.cs
0.00MB

'유니티좀비게임 > 생명과 좀비' 카테고리의 다른 글

좀비(Enemy) 오브젝트 준비  (0) 2023.05.03
네비게이션 시스템  (0) 2023.05.03
플레이어 체력 UI  (0) 2023.04.30
Event  (0) 2023.04.28
객체지향 다형성 LivingEntity  (0) 2023.04.28

+ Recent posts