9. 적 캐릭터 제작(1)

MOON·2022년 7월 19일
0

유니티_3D_SpaceShooter

목록 보기
9/11
post-thumbnail

개요

자신만의 인공지능(AI)를 가지고 있어야 현실감 있는 게임

FSM(Finite State Machine : 유한상태머신)
적 캐릭터가 스스로 알아서 주변환경에 적응, 들어오는 반응에 적절하게 반작용 하는 상태
생성되면 주변 순찰 - 플레이어를 만나면 추적 시작 - 사정거리 내에 근접하면 공격 시작 - 데미지를 입고 생명이 다하면 사망

FSM의 단점
상태가 많아질 수록 상태와 상태간의 연결(Transition)이 복잡해 짐
코드의 확장과 유지 보수가 어려워짐
이러한 점을 보완히기 위해 계층적 유한상태 머신( HFSM : Hierarchical Finite State Machine)
행동 트리 (BT : Behavior Tree) 방식 개발 이루어짐


메카님

메카님
유니티의 애니메이션 상태머신 시스템, 애니메이션 미들웨어 엔진
FSM 상태에 따라 적절한 애니메이션 조작을 메카님을 이용하여 구현함
시각적인 설계방식을 제공함

Humanoid Type vs Generic Type

Humanoid : 팔(2개), 다리(2개), 머리(1개)를 가진 인간형 캐릭터 -> 리타겟팅(ReTargetting) 시스템을 사용하여 애니메이션을 공유 할 수 있음
예) 오크/ 엘프/ 사람 … 같은 애니메이션 공유

Generic : 인간형을 제외한 4족 보행동물, 슬라임과 같은 기타 메시등을 일컬음
리카겟팅 기능이 제공되지 않고 메카님을 이용하여 애니메이션 처리


몬스터 3D 모델 임포트

“Resource/Models”에서 Monster 패키지를 임포트한 후 05.Models로 옭김
idle/walk/run/jump/fall/attack 등과 같은 애니메이션을 포함


메카님 애니메이션으로 전환


Avatar Configuration 화면 : Configuration 버튼을 클릭하여 본 매핑에 대한 정보를 확인 할 수 있음
필수적으로 연결해야 하는 본 : 15개


애니메이션 클립 속성

애니메이션 클립의 Loop Time 옵션 체크
3개의 애니메이션 클립(idle/walk/attack)만 Loop Time 체크
맨 아래의 Apply 버튼을 체크함




애니메이션 리타겟팅

메카님 애니메이션 장점 - 리타겟팅이 가능
리타겟팅 : 다른 애니메이션 동작을 가지고 와서 적용이 가능
메타님 애니메이션에서 리타게팅을 사용하려면 모델과 애니메이션 클립의 Animation Type 둘다 Humanoid 로 설정이 되어 있어야 함

적용 방법
www.mixamo.com
“gannam” 으로 검색 (강남스타일)
혹은 Resource/Animations 에서 Monster@Ganam Style.fbx 파일을 사용해도 됨
Monster@Ganam Style.fbx 를 선택 [Rig]탭에서 Animation Type을 Humanoid 로 설정 -> Apply


리타겟팅 실행 결과
프로젝트 뷰의 Monster 모델을 드래그 해서 미리보기 창에 확인 가능

Player VS Monster 의 Animation Type 및 Animation 컴포넌트


애니메이터 컨트롤러

메카님을 적용한 모델에 애니메이션을 적용하고, 특정 조건에 따라 다른 애니메이션 상태로 전이하는 규칙을 설계할 수 있다.
07.Animation 폴더 아래에 “Controlls”폴더를 만든 후 [Assets] - [Create] - Animation Controller를 생성하고 이름을 MonsterAnim으로 변경

초기 애니메이션 상태 지정 : idle state


Monster의 Animator 컴포넌트의 Controller 속성에 MonsterAnim 콘트롤러를 연결
현재 idle상태로 초기화 됨
실행하면 idle상태바가 움직이는것을 확인 할 수 있음


스테이트 전이와 파라미터

상태 전이 (idle -> Walk) 구현
walk 상태 노드를 위치시킨 후 idle 노드에서 오른쪽 마우스 클릭, Make Transition 선택
왼쪽의 Parameter탭에서 Bool 타입의 변수 생성(변수명 ; IsTrace)
IsTrace (true) : idle ->walk 로 전이
IsTrace (false) : walk -> idle 로 전이


Has Exit Time 속성
속성이 체크되면 즉각적인 상태 전이가 일어나지 않고 애니메이션이 다 끝난 다음 다음 상태로 변경 됨, 화살표를 클릭하면 Inspector창에서 확인 가능함
Conditions속성에서 IsTrace 변수에 true로 설정
IsTrace 변숫값이 true가 되면 바로 전이를 발생시키기 위해 Has Exit Time 속성을 언체크 함



몬스터 따라오기

네비게이션 기능
기존의 길찾기 알고리즘(Path Finding, A*)을 대처, 유니티에서 독자적으로 제공
3D 메쉬정보를 분석해 걸어갈수 있는 영역과 지나갈 수 없는 영역으로 구분한 정보를 바탕으로 런타임시 그 정보를 활용하여 최단거리 를 계산해 추적할 수 있게 하는 기능

네비게이션 설정 및 베이크 (미리 만들어 놓음)
네비게이션을 베이크 하려면 Floor의 Static 옵션을 Navigation Static으로 바꿈(모두 static 으로 바꾸는 것이 아님) -> Navigation Flag 설정


네비게이션 베이크
Floor를 선택
메뉴 - Windows - AI - Navigation
오른쪽 하단의 Bake 버튼 클릭

Barrel 오브젝트로 네비게이션 베이크 함
드럼통은 프리펩이므로 차일드 객체에도 적용해야 하기 때문에 경고문이 뜨고 Yes를 체크함

Nav Mesh Agent 콤포넌트
실제로 플레이어를 추적할 수 있게 하는 컴포넌트
베이크 된 네비게이션 메쉬를 분석하여 장애물을 회피하고 목표물까지 최단거리를 계산하고 추적하게 할 수 있다.

메뉴-Component-Navigation-Nav Mesh Agent 를 선택한 후 Monster


Sopping Distance
추적하다가 정지하는 근접거리, 플레이어와의 거리, 0 이면 플레이어와 겹치게 됨

Player태그를 만들어 지정도록 한다
플레이어의 위치정보를 스크립트 상에서 가져오기 위해 필요함
Hierarchy 뷰에 존재하는 모든 게임오브젝트중 지정한 태그를 달고 있는 게임 오브젝트를 찾아 준다.
GameObject.FindWithTag(“태그명”)


MonsterCtrl.cs 스크립트를 만들어보자.

NavMeshAgent를 사용하시 위해서는 using문에 AI를 적어주어야 한다.
몬스터 위치, 플레이어 위치, 컴포넌트 저장할 변수를 선언한다.
Start함수에서 컴포넌트를 GetComponent 통해 가져오고, FindWithTag()를 통해 특정 오브젝트를 찾아낸다.

destination은 에이전트에 이동시키고자 하는 포인트까지의 경로를 산출시킬 수 있습니다. 산출이 완료되는 즉시 에이전트는 자동으로 경로를 따라 이동하여 목표에 도달합니다.


인공지능 구현(따라오기)


적 캐릭터의 상태 체크

FSM 은 자신의 상태 값을 갖고 있어야 하며 현재 어떤 상태인지 갱신하고 해당 상태에 맞는 행동을 취해야 한다.
적 캐릭터의 상태를 순찰(Idle)/추적(Trace)/공격(Attack)/사망(Die) 으로 정의한다.

MonsterCtrl.cs : 스크립트 수정하자

변수에 있는 enum은 열거형으로 나열할때 사용한다.
필요한 변수들과 열거형 변수를 이용해 현재 상태를 저장한다.

적었던 코드들을 주석처리하고 코루틴 함수를 이용하겠다.
코루틴 함수 시작시 StartCoroutine()를 사용한다.

IEnumerator을 같이 적어주며 while문을 적어주어 죽지않을때까지 실행합니다.

0.3초 간격을 주며 주인공과 몬스터의 거리를 측정합니다.
만약 거리가 공격 사정거리보다 가까워지면 ATTACK를 실행합니다.
다른 경우로 추적 사정거리 범위에 있으면 몬스터가 TRACE를 하고, 아니면 기본 IDLE를 유지합니다.


위 코드들은 적의 추적 사정거리를 그려주는 함수이며 추적과 공격의 색깔을 다르게 그려보았다.


플레이어가 가까이 가면 WireFrame 형태의 반 구가 생김
기즈모 : 주인공 캐릭터가 접근해 몬스터의 상태가 변경되는 것을 시각적으로 표현하기 위해 사용
추적 사정 밖 (IDLE)
추적 사정거리 안(TRACE) : 파란색
공격 사정거리 이내 (ATTACK) : 빨간색
인스펙트 뷰에서 IDLE/TRACE/ATTACK 상태가 변경되는것을 확인 할 수 있음

별도의 코루틴 함수를 만들어서 사용(확장성과 코드의 간결함을 위함)
MosterCtrl.cs Start()함수에 아래 코드 1줄을 적어주자.

StartCoroutine(MonsterAction());


switch 문을 사용해 상황에 따라 다르게 동작시킨다.
몬스터가 플레이어의 위치까지 계속(일정 거리 를 유지하면) 따라오는것을 확인 할 수 있음


애니메이션 동기화

애니메이터 컴포넌트를 저장할 변수를 선언한다.

private Animator anim;

파라미터를 bool형태로 했으므로 실행 시키기 위해 SetBool()로 시킨다.
Animator 뷰에서 애니메이션 전이가 일어나는것을 확인할 수 있음


몬스터 공격 루틴

Animator 뷰에서 Animator 뷰에서 attack 애니메이션 클립을 배치 한 후 walk 스테이트와 양방향 Transition을 연결함

MonsterCtrl.cs 수정하자

파라미터의 이름을 문자열로 전달하면 오류 발생할 수 있음
애니메이터 컨트롤에 정의한 파라미터는 모두 해쉬 테이블로 관리함 .. 애니메이터 뷰의 해시 값을 미리 추출해 인자로 전달 (속도 향상 효과)

해시 값을 저장한 변수를 바꾸어서 적어준다.

플레이어가 발사한 총알이 몬스터에 명중했을 때 타격을 입는 리액션 구현
Monster를 선택한 후 Capsule Collider를 추가 함

몬스터가 총알에 맞았을 때의 애니메이션 설정
Parameters에서 Trigger 변수를 새롭게 만든다.

업로드중..

gohit 상태(리액션 애니메이션) 는 몬스터가 어떠한 상태이든 발생할 수 있기때문에 모두 연결을 시도해야 한다
gohit 애니메이션을 90% 수행하고 다음 스테이트로 넘어 갈 수 있도록 Has Exit Time 옵션을 체크함
0.0 ~ 1.0 사이의 값을 가지며 0.9는 90% 를 의미한다.

업로드중..

MonsterCtrl.cs 에 OnCollisionEnter() 함수 추가
몬스터가 총알에 맞았을 경우에 대해 코드 구현

private readonly int hashHit = Animator.StringToHash("Hit");

정수형 해시값으로 바꿀수 있도록 변수를 선언한다.

anim.SetTrigger(hashHit);

위 코드를 OnCollisionEnter()에 있는 if Bullet부분에 적어준다. 트리거 함수는 인자값에 해시부분에 적어주면 된다.


이것으로 적 캐릭터 제작(1)을 마무리하고 다음 부분으로 넘어가겠다.
profile
나만의 공간

0개의 댓글