본문 바로가기

3D_FPS

08_16 애니메이션 IK , NevMesh

목차

 


저번 시간 복습 및 Tree,Graph 자료구조

 

코루틴을 사용할때의 몇가지 장점

 

=> Idle Time 을 확보할 수 있다.

유휴시간을 늘려서, CPU 가 대기를 많이 하고 있어서, 성능을 높일 수도 있음.

 

근데 이걸 남발하게 되면 정말 문제가 됨..

우리는 아직 그런 실력이 안되기때문에, 글쓰기 연습을 열심히 하자!

Tree 자료구조 공부해보기!!!

https://ansohxxn.github.io/algorithm%20lesson%202/chapter5-1/

 

Chapter 5-1. 트리 이론과 구현

인프런에 있는 Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part2: 자료구조와 알고리즘 강의를 듣고 정리한 필기입니다. 😀 🌜 강의 들으러 가기 Click

ansohxxn.github.io

Graph 자료구조도 공부해보기!!

https://hongcoding.tistory.com/78

 

그래프(Graph) 개념정리 (자료구조)

그래프란? 그래프는 정점(Vertex)과 간선(Edge)으로 이루어진 자료구조이다. 정확히는 정점(Vertex)간의 관계를 표현하는 조직도라고 볼 수 있다. 이러한 면에서 트리는 그래프의 일종인 셈이다. 하지

hongcoding.tistory.com

트리 구조 vs 그래프 구조 생김세
그래프 순회 알고리즘 2가지

 

어떻게 보면 트리구조도 그래프구조의 일종이다.

 

트리구조 쓰는 이유

 

----

수업에서 말 하지는 않은 건데,

애니메이터 State 를 클릭해보면 Inspector 창에  AddBehaviour 버튼이 있음

 

이럴 때 보면

OnstateEnter 

OnstateExit

OnstateUpdate

여기서 코드로 쓸 수 있는데, 이건 Unity 가 제어하는게 되버림.

뭔가 애매한게 있기 때문에, 여튼 이런건 비추!!


애니메이션 Inverse Kinematics 구현

 

--------

IK, FK

팔을 들 때, 어깨를 들어서 팔꿈치를 들어서 손으로 잡는다.

이게 Forward Kinematics 임

 

----

손목을 들었을때, 팔꿈치와 어깨가 들린다

이게 Inverse Kinematics 임

 

동적인 애니메이션을 쓸 때 IK 를 많이 씀

손으로 뭘 짚는다고 치면, 손을 그 땅에 대고, 팔꿈치 어깨가 같이 움직여야 하니까!

 

이런 방식은 IK임!!

 

유니티에서 제공하는  IK는? 몸통 빼고

이렇게만 IK 를 사용함

현재는 몸통의 IK 까지는 없음

그래서 이렇게 물건을 줍는 에니메이션을 할 때는 허리를 굽는게 아니라,

왼쪽 처럼, 팔만 늘어나서 줍는 느낌으로 된다.


 

 

 

IK 로

달을 쳐다보게 해보자!

 

Sphere 로 달을 하나 만들고,

 

IKTest 라는 이름의 스크립트를 만들어서

이 건담 프리펩한테 assign 을 해보자!

 

animator 컴포넌트 받은 모습

바라볼 target Transform 도 설정 하자!

 

그리고 ONAnimatorIK 라는 함수를 생성!

 

아까만든 Sphere 의 트랜스폼을 IKTest 에 넣은 모습
보게하는 코드를 넣는다

 

달을 쳐다본다..ㄷㄷ

 

(참고)

손이 아이콘을 따라갈때

벽타기 할 때, Lay 를 쏴서 hit 포인트에 손을 가져다 두게 할 수 있음

 

handTarget 생성

 

이제는 IK로 손의 위치를 제어시켜보자!

 

 

손이 만들어준 handTarget 을따라가는 모습

 

 

handTarget의 회전값으로 이 손의 회전값 까지 조절 해줄 수 있다!

 

아이콘을 회전시키면 팔도 회전됨!
총 쪽에 대면

이렇게 총에 대고 있는것 처럼 보임!!

근데 저 아이콘을 계속 따라다니는것 처럼 보이기 때문에 총이랑 같이 애니메이션이 움직이지 않는다.

 

기울어진 경사에 서있게 하려면

경사진곳 애니메이션

이 느낌 내게 하려면 IK 같은걸 쓴다. Ray 를 쏴가지고. 근데, 이런거 하려면 발목에 회전값도 줘야함!


NavMesh 설명

IK는 꺼놓고 가자

 

네비게이션은 기본적으로 A Star 알고리즘을 쓴다.

A*  알고리즘은 이런걸 개선함(최단거리 찾기)

근데 실시간으로 찾으려고 하니까, 성능이 떨어져서 잘 안씀

폴리곤이 여러개이면 Mesh

갈 수 있는곳 없는곳 미리 Mesh 형태로 뜬다고 해서 Nav Mesh 라고 부름

 

이건 가상에서 쓰임!! 가상공간을 시뮬레이션으로 미리 만들어 놓은게 Nav Mesh 임!

 

가상공간을 움직이는 영화중에 Matrix 가 있음

 

메트릭스에서 가상공간에서 움직일 수 있는애들

 

(참고)

AI 에서도 Agent 라는 단어가 많이 나옴! 강화학습 단계에서.

 


NavMesh 시스템 구현

 

일단 맵들을 Empty GameObject 에 넣어보자

이름은  Environment
Environment의 inspector 에서 static 열어본 상태

 

 

static Batching

유니티 project Settings -> Player 에 보면 Static Batching 이 있다.

이건 Static 끼리 합쳐주는 역할 을 한다

 

Mesh들을 Static 하면 합쳐서 그려버림

이걸 batching 이라고함

길찾기에 관련된것들
Static 으로 만들거니까 체크해준다.
CHildren 까지 다 눌러줌!
Windows -> Navigation 추가
이제 Navgation 관련된 정보를 볼 수 있음!

 

0.75 -> 계단부분의 높이 (여기까지 갈 수 잇음)

 

45도 까지 올라갈 수 있게 할 수 있음 (Max Slope)

Area 에는 계산 비용과 관련이 있다.

비용이 높을수록 우선순위권이 있는것임!

 

Not Walkable => 그쪽으로 가지 못하게 만든는것

점프할 수 있는곳 까지 넣어줄 수 있음!

Bake 누르자!

 

Agent 는 이제 파란색 부분만 움직일 수 있음


NavMeshAgent 움직임 제어(점프)

 

어떻게 갈 지 우리가 설계해 볼 거임

이 상황에서는, Agent 가 어떻게 갈지 알 수 없다. 그냥 최단 거리로만 갈 뿐이다.

이 상태에서 우리가 어떻게 갈지 설계해보자

 

Enemy 에 Nav Mesh Agent 추가

Enemy 를 Agent 로 쓸거니까  Nav Mesh Agent 컴포넌트를 추가한다

 

 

Enemy 코드부분

Enemy.cs

Enemy.cs 에 UnityEngine.AI 네임스페이스를 넣는다.

 

네비메쉬에이전트 선언

 

Start 에 넣자

컴포넌트 받아오기

 

Move() 함수에서 이동하는 코드를 주석처리

이제 Agent 로 움직일 거니까, Move() 에서 움직임을 담당한 코드를 주석처리 하자!

 

이 코드를 넣자!

agent.destination = target.position; 

코드를 넣어서 움직이게 할 수 잇다.

 

실행 해보자


여기서 문제!

 

이렇게 하면 공격하면서 감!!

멈추고 공격하게 하고싶다!

 

그러면 저 코드 밑에

agent.stoppingDistance 를 써도 되는데, 이게 관성때문에 좀 미끌어짐.

 

그래서

공격범위보다 거리가 작으면 agent 를 꺼버리자.

 

agent.enabled = false; 를 넣으면 동작 자체가 멈추기 때문에 좀 더 깔끔하다!

 

Move 로 갈때도 true!

Move 로 가면 다시 켜줘야 하니까, 이 조건문에 이렇게 넣어준다.

 

Idle 에서 Move 로 갈때도 true!!

 


근데 여기서 또 문제,

다른곳을 보면서 공격한다,,?

 

Player 를 보고 계속 때리고 싶음!!

Move() 에서 썼던 이 코드를 참고해서, Attack() 에 넣어주자!

넣어준 모습

 

 


OffMeshLink (점프) 구현

 

OffMeshLink 를 알아보자.

점프 뛰어서 가고싶을때는 어떻게,,?
Ground 만 복제 해서 오른쪽에 놓자!

 

플레이어는 그냥 오른쪽으로 가져다 놓자.

Enemy 를 오른쪽으로 점프시키게 할거임!

Bake 하는 곳에서

Jump Distance 를 2 로 두고 방금 만든 Ground 까지 해서

Clear -> Bake 한다.

 

 

이렇게 하면 가긴 가는데 점프느낌이 아님 ㅜㅜ 그니까 일단 JumpDistance 0 으로 하고 다시 베이크

 

 

점프 구간 없어진 모습

 

포지션을 각각 만들어서 구현 해보자.

NavMesh , JumpStart , JumpEnd 만들기

그냥 다 빈게임오브젝트임

그리고 스타트랑 엔드 포인트를 NavMesh 안에 넣자.

 

start -> End

이렇게 포인트에서 포인트로 점프시키게 할거임

 

Start 와 End 를 이렇게 배치한다.

 

여기에 OffMeshLink 컴포넌트 추가

 

Bideirectional -> 스타트로 갔으면 반대로도 다시 올 수 있게하는 것, 체크 해주자.

Navigation Area 를 Jump 로 설정 해줌! 점프시켜줄거니까

 

 


 

(참고)근데 만약에,  그라운드가 새로운씬에 있다고 하면?

다른씬이 이렇게 되어있다고 치자

 

이렇게 씬 다른게 있어도, 알아서 붙어짐,,! 유니티의 기능


Nav Mesh Obstacle 시스템 구현

 

 

다시 돌아와서, Ground 복제 했던거 없애고

이제 이 오브젝트를 점프해서 오게 해보자.

 

아까 start end 포인트를 장애물 Object 양쪽에 배치해서 올라올 수 있게 해보자

 

옆으로 돌아오는 모습

최단거리가 옆으로 돌아오는거라서, 그렇다.

오브젝트를 더 늘려보자

 

늘리면 점프해서 옴!

 

 

이 오브젝트를 클릭하고 Navigation 으로 가서

Object 부분을 클릭 해보자.

여기서 Navigation Area 에서 Not Walkable 을 클릭하게 되면

Enemy 는 이 부분을 가지 못한다.

베이크 해본 모습

 

하나만 남겨놔보자

오브젝트 올라가느라 복제해서 두개 썼었는데 하나 꺼보자.

 

 

다리만들기

큐브 하나 생성해서, 색 바꾸고 Bridgy 형태로 써볼 예정!

 

Nav Mesh Obstacle

저렇게 두고 Nav Mesh Obstacle 컴포넌트를 넣고

 

카브 체크

Carve 를 체크해보면

 Enemy(agent) 는 이 장애물을 장애물로 인식하여 지나가지 않는다!

 

 

장애물 세팅
Carve On

Carve 를 켰을 때 장애물인줄 알고 돌아가는 모습

 

Carve Off

끄고 통로만들어주면 이 방향으로 온다.

그냥 공중에 들어줘서 오는것 처럼 보이지만,

 

그게 아니라 끈 순간부터 여기를 장애물로 인식하지 않아서 여기를 통해서

플레이어에게 오려고 함!

 

콜라이더 있으니까 들어준거임!


내일은 Patrol 기능을 해볼거임!!

 

멀리있으면 그냥 제 자리에서 배회하고,