유니티 3D게임 쿼드뷰 09

유니티 3D게임 쿼드뷰 09

Summary 유니티 3D 게임 개발에 있어 적 AI 구현을 위해 GetComponentInChildren<>();와 NavMeshAgent를 사용하며, NavMesh 베이킹을 통해 적이 플레이어를 잘 따라오도록 설정합니다. 애니메이터 컨트롤러를 통해 적의 애니메이션을 관리하고, 공격 범위를 설정하기 위해 SphereCastAll을 활용하여 플레이어를 타겟팅하는 코드를 작성합니다.


🎥 동영상 보기

🔥 Enemy A에 Enemy.cs 를 넣으면 다음과같은 에러가뜨는데, 자식들의 컴포넌트값까지 받아온다는 의미로 InChildren을 추가하면 정상적으로 meshRender를 불러옵니다 Image

1
2
3
4
5
6
private void Awake()
    {
        rigid = GetComponent<Rigidbody>();
        boxCollider = GetComponent<BoxCollider>();
        mat = GetComponent**InChildren**<MeshRenderer>().material;
    }

🔥 Nav Mesh Agent = 네비게이션을 사용하는 인공지능 컴포넌트 Image

1
2
3
4
5
6
//Enermy.cs
using UnityEngine.AI; //AI 모듈을 쓰기 위해선 해당 라이브러리 추가

public Transform target; //목표물을 받아내기위한 변수

NavMeshAgent nav; //AI모듈이 추가되면 해당 네비게이션 변수를 만들어낼 수 있음
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
private void Awake()
    {
        nav = GetComponent<**NavMeshAgent**>();
    }

void Update()
    {
        //도착할 목표 위치를 지정하는 함수
        nav.**SetDestination**(target.position);
    }

Image

🔥 NavMesh = NavAgent가 경로를 그리기 위한 바탕

Window - AI - navigation

클릭하면 창이 뜨는데

Image

Image

🔥 NavMesh는 Static 오브젝트에서만 Bake가 가능함 Image

Image

🔥 적 애니메이션 제작 Image

Image

Image

애니메이터 컨트롤러 제작하여 메쉬오브젝트 내부에 넣기

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//Enemy.cs

Animator anim;

void Awake()
    {
        rigid = GetComponent<Rigidbody>();
        boxCollider = GetComponent<BoxCollider>();
        mat = GetComponentInChildren<MeshRenderer>().material;
        nav = GetComponent<NavMeshAgent>();
        anim = GetComponentInChildren<Animator>();
    }

🔥 버그발생.. 코드 다 똑같은데 왜 몬스터 상태 이따구냐 Image

Image

해결 : MeshObject에만 애니메이터가 있어야했는데 내가 둘 다 넣어서 충돌문제다

🎥 동영상 보기

🔥 **MeshRenderer[]** meshes; 팔,다리 몸통별로 따로따로 메쉬렌더러를 가지고 있기 때문에 배열로 선언

1
2
3
4
5
6
7
8
9
//Plater.cs

MeshRenderer[] meshes; //팔,다리 몸통별로 따로따로 메쉬렌더러를 가지고 있기 때문에 배열로 선언

void Awake()
    {
        meshes = GetComponentsInChildren<MeshRenderer>();
				//Components 복수형이다 참고하시길
    }

🔥 몬스터 공격 코드

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void Targeting()
    {
        float targetRadius = 1.5f;
        float targerRange = 3f;

        //부피가 있는 레이케스트를 활용하여 피격범위 설정
        //범위내에있는놈들 싹다 죽여야하기때문에 배열로 생성
        //SphereCastAll(시작위치,반지름,레이케스트발사방향,레이케스트길이,레이어마스크) 구체모양의 레이캐스팅
        RaycastHit[] rayHits = Physics.SphereCastAll(transform.position, 
                                                    targetRadius,transform.forward,targerRange,
                                                    LayerMask.GetMask("Player"));
        Debug.DrawRay(transform.position, transform.forward * targerRange,Color.green);
        //rayHits변수에 데이터가 들어오면 공격 코루틴 실행
        //만약 공격 범위 안에 플레이어가 들어왔다면?
        if(rayHits.Length > 0 && !isAttack)
        {
            StartCoroutine(Attack());
        }
    }

    IEnumerator Attack()
    {
        isChase = false; //쫓아가지 않는 상태 활성화
        isAttack = true; //공격상태 활성화
        anim.SetBool("isAttack",true); //공격 애니메이션 활성화
        yield return new WaitForSeconds(0.2f);
        meleeArea.enabled = true; //공격범위 활성화
        yield return new WaitForSeconds(1f);
        meleeArea.enabled = false; //공격범위 비활성화

        isChase = true;
        isAttack = false;
        anim.SetBool("isAttack",false);
    }

Image

💬 댓글

GitHub 계정으로 로그인하여 댓글을 남겨보세요. GitHub 로그인

🔧 댓글 시스템 설정이 필요합니다

GitHub Discussions 기반 댓글 시스템을 활성화하려면:

  1. Giscus 설정 페이지에서 설정 생성
  2. GISCUS_SETUP_GUIDE.md 파일의 안내를 따라 설정 완료
  3. Repository의 Discussions 기능 활성화

Repository 관리자만 설정할 수 있습니다. 설정이 완료되면 모든 방문자가 댓글을 남길 수 있습니다.