1 00:00:05.749 --> 00:00:10.069 게임 심화편 내비게이션 시스템 2 00:00:23.550 --> 00:00:26.050 안녕하세요 이영훈입니다 3 00:00:26.050 --> 00:00:30.679 이번 시간에 알아볼 내용은 내비게이션 시스템입니다 4 00:00:30.679 --> 00:00:34.829 이번 단원에서는 언리얼의 길 찾기 시스템인 5 00:00:34.829 --> 00:00:38.239 내비게이션 시스템에 대해 학습하겠습니다 6 00:00:38.239 --> 00:00:41.119 그리고 Navigation Invoker를 이용해 7 00:00:41.119 --> 00:00:43.469 실시간으로 길을 생성하고 8 00:00:43.469 --> 00:00:46.959 목적지를 향해 이동하는 방법을 학습하겠습니다 9 00:00:46.959 --> 00:00:50.009 또한 이를 이용해 패트롤 기능을 10 00:00:50.009 --> 00:00:52.439 구현하는 방법을 학습하겠습니다 11 00:00:52.584 --> 00:00:56.724 내비게이션 시스템을 이용한 길 찾기 12 00:00:58.239 --> 00:01:02.619 이번에는 길 찾기 처리를 해볼 건데요 13 00:01:02.619 --> 00:01:06.379 기본적으로 에너미가 플레이어를 향해서 이렇게 오죠 14 00:01:06.379 --> 00:01:12.339 그런데 만약에 사이에 장애물이 있다면 어떻게 될까요? 15 00:01:12.339 --> 00:01:18.879 큐브를 하나 배치해서 결과를 잠깐 보도록 할게요 16 00:01:18.879 --> 00:01:24.479 이렇게 장애물을 만들고 실행을 해보면 17 00:01:24.479 --> 00:01:28.839 에너미가 플레이어 쪽으로 올 수가 없습니다 18 00:01:28.839 --> 00:01:32.939 그거는 왜냐면 에너미는 지금 직진을 하고 있거든요 19 00:01:32.939 --> 00:01:37.239 앞쪽으로 플레이어 방향으로 가기 위해서 20 00:01:37.239 --> 00:01:40.519 이렇게 방향을 정하고 21 00:01:40.519 --> 00:01:43.309 그 방향으로 이렇게 AddMovementInput을 통해서 22 00:01:43.309 --> 00:01:45.499 그 direction으로 쭉 오고 있는 거예요 23 00:01:45.499 --> 00:01:48.259 그런데 그 방향에 어떤 장애물이 있거나 24 00:01:48.259 --> 00:01:51.800 그렇게 되었을 때는 제대로 이동할 수가 없겠죠 25 00:01:51.800 --> 00:01:55.700 그래서 이런 언리얼이라던지 이런 엔진에서는 26 00:01:55.700 --> 00:01:57.400 이런 것들을 처리하기 위해서 27 00:01:57.400 --> 00:01:59.360 길 찾기 시스템을 제공하고 있는데요 28 00:01:59.360 --> 00:02:01.360 보통 그런 것들을 영어로 하면 29 00:02:01.360 --> 00:02:08.180 Path Finding이라고 하죠 30 00:02:08.180 --> 00:02:09.180 이렇게 얘기를 하고 31 00:02:09.180 --> 00:02:15.039 다른 말로 Navigation이라고 합니다 32 00:02:15.039 --> 00:02:16.759 이렇게 부르기도 하고요 33 00:02:16.759 --> 00:02:20.679 그러면 언리얼에 있는 내비게이션 시스템을 이용해서 34 00:02:20.679 --> 00:02:24.759 이것을 제작을 해볼 건데요 35 00:02:24.759 --> 00:02:28.909 보통 Navigation, Path Finding 이런 걸 하면 36 00:02:28.909 --> 00:02:34.039 대부분 가장 유명한 알고리즘이 있죠 37 00:02:34.039 --> 00:02:37.759 알고리즘 중에 A* 알고리즘이 있습니다 38 00:02:37.759 --> 00:02:41.759 이거는 기본적으로 이렇게 면이 있으면 39 00:02:41.759 --> 00:02:45.099 여기에서 최단거리 길 찾기를 하는 개념이고요 40 00:02:45.099 --> 00:02:46.699 예를 들어서 이렇게 41 00:02:46.699 --> 00:02:50.479 배열처럼 이렇게 되어 있는 것들이 있다면 42 00:02:52.079 --> 00:02:54.679 예를 들어 여기에서 여기까지 빨리 가고 싶어요 43 00:02:54.679 --> 00:02:57.299 그러면 여기에 만약에 장애물이 이렇게 있어요 44 00:02:57.299 --> 00:03:00.759 그러면 예를 들어 이렇게 장애물이 있다고 해보죠 45 00:03:00.759 --> 00:03:04.609 그러면 원래는 이렇게 이렇게 가는 게 가장 빠른데 46 00:03:04.609 --> 00:03:07.759 이렇게 이렇게 이동하게 되겠죠 47 00:03:07.759 --> 00:03:09.279 이게 더 복잡해질수록 48 00:03:09.279 --> 00:03:12.759 더 많은 그런 계산을 하게 될 겁니다 49 00:03:12.759 --> 00:03:16.599 기본적으로 이 A* 알고리즘을 이용해서 50 00:03:16.599 --> 00:03:18.759 길 찾기를 하게 되고요 51 00:03:18.759 --> 00:03:21.189 사실 A* 알고리즘은 이렇게 사각형 형태만 52 00:03:21.189 --> 00:03:22.759 할 수 있는 게 아니라 53 00:03:22.759 --> 00:03:25.659 삼각형도 할 수 있고요 54 00:03:25.659 --> 00:03:29.299 이렇게 생긴 삼각형을 이용할 수도 있고요 55 00:03:29.299 --> 00:03:32.979 혹은 이렇게 오각형이나 육각형, 팔각형 56 00:03:32.979 --> 00:03:35.759 이런 것들을 이용해서도 할 수가 있습니다 57 00:03:35.759 --> 00:03:40.279 그래서 현재 이 면과 인접한 다른 면의 58 00:03:40.279 --> 00:03:42.829 길을 만들고 가장 가까운 최단거리를 59 00:03:42.829 --> 00:03:47.419 구하는 공식이라고 보시면 되는데요 60 00:03:47.439 --> 00:03:50.239 언리얼에도 이런 식으로 구현이 되어 있고요 61 00:03:50.239 --> 00:03:53.419 그러면 이것을 처리하기 위해서 기본적으로 62 00:03:53.419 --> 00:03:55.619 어떤 데이터를 만들어야 되거든요 63 00:03:55.619 --> 00:03:58.359 그래서 이거를 좀 간단하게 말하면 64 00:03:58.359 --> 00:04:00.299 길을 만들어야 된다고 할 수 있어요 65 00:04:00.299 --> 00:04:02.759 길이 있어야지 이동을 할 수가 있고요 66 00:04:02.759 --> 00:04:08.139 그러면 언리얼에서 이 길 찾기를 하기 위해서 67 00:04:08.139 --> 00:04:11.219 필요한 요소가 크게 보면 두 가지가 있습니다 68 00:04:11.219 --> 00:04:13.669 하나는 길입니다 69 00:04:13.669 --> 00:04:16.359 길이 있어야 돼요 그래야지 갈 수 있고요 70 00:04:16.359 --> 00:04:20.409 두 번째는 실제로 찾아가는 주체가 있어야 돼요 71 00:04:20.409 --> 00:04:29.500 길을 찾는 컨트롤러라고 할 수 있죠 72 00:04:29.500 --> 00:04:32.200 어떻게 보면 길 찾기는 인공지능이죠 73 00:04:32.200 --> 00:04:35.140 이거를 AI라고도 할 수 있어요 74 00:04:35.140 --> 00:04:38.040 인공지능인데 이렇게 해서 75 00:04:38.040 --> 00:04:40.600 그 인공지능에 해당하는 처리하는 녀석이 바로 76 00:04:40.600 --> 00:04:43.360 길을 찾는 컨트롤러라고 할 수 있고 77 00:04:43.360 --> 00:04:50.760 여기에서는 AIController라고 합니다 78 00:04:50.760 --> 00:04:52.510 이렇게 얘기를 할 수 있어요 79 00:04:52.510 --> 00:04:57.760 그래서 먼저 길과 컨트롤 이렇게 만들어 보면 되는데요 80 00:04:57.760 --> 00:05:01.760 기본적으로 길을 만들기 위해서는 81 00:05:01.760 --> 00:05:05.060 여기 보시면 Place Actors에 82 00:05:05.060 --> 00:05:07.300 Volumes이라는 부분이 있습니다 83 00:05:07.300 --> 00:05:13.210 Volumes이라는 곳으로 오셔서 여기에서 84 00:05:13.210 --> 00:05:16.320 Nav Mesh Bounds Volume이라는 게 있어요 85 00:05:16.320 --> 00:05:18.460 이거를 이렇게 꺼냅니다 86 00:05:18.460 --> 00:05:21.240 이게 이제 길을 만들어내는 그런 볼륨 87 00:05:21.240 --> 00:05:24.980 어떤 영역을 만들어낼 수가 있는데요 88 00:05:24.980 --> 00:05:28.250 이걸 이용해서 한번 해보도록 할게요 89 00:05:28.250 --> 00:05:32.520 그러면 Volume을 보시면 90 00:05:32.520 --> 00:05:36.480 여기에 크기를 지정할 수가 있습니다 91 00:05:36.480 --> 00:05:39.180 크기를 일단은 센터에 놓고요 92 00:05:39.180 --> 00:05:45.940 크기를 넓혀주면 되는데 93 00:05:45.940 --> 00:05:48.940 여기 보시면 Brush Settings이라는 곳이 있어요 94 00:05:48.940 --> 00:05:50.840 이거를 건드려도 되고 95 00:05:50.840 --> 00:05:53.220 아니면 Scale을 건드려도 됩니다 96 00:05:53.220 --> 00:05:55.720 둘 중 하나를 만져주시면 되는데 97 00:05:55.720 --> 00:05:58.320 저는 여기 있는 Brush Settings으로 해볼게요 98 00:05:58.320 --> 00:06:00.570 이것을 선택하고요 99 00:06:00.570 --> 00:06:03.740 적당하게 한 2000이라고 해볼까요? 100 00:06:03.740 --> 00:06:05.760 그러면 이정도 되네요 101 00:06:05.760 --> 00:06:07.210 그러면 더 커야 될 것 같습니다 102 00:06:07.210 --> 00:06:14.700 지금 보니까 한 4배? 8000이라고 해볼까요? 103 00:06:14.700 --> 00:06:19.760 그러면 이 정도 되네요 그리고 Y로도 8000 104 00:06:19.760 --> 00:06:25.760 이렇게 하면 가득 차게 되죠 105 00:06:25.760 --> 00:06:28.440 Z는 굳이 안 만져도 될 것 같고요 106 00:06:28.440 --> 00:06:32.860 이 상태에서 실제로 길이 어딘지 볼륨을 보려면 107 00:06:32.860 --> 00:06:34.710 아무것도 누르지 않은 상태에서 여기 108 00:06:34.710 --> 00:06:36.970 뷰포트를 선택한 상태에서 109 00:06:36.970 --> 00:06:40.760 P버튼을 한번 눌러보세요 키보드에 P키가 있죠? 110 00:06:40.760 --> 00:06:43.160 P를 누르시면 이렇게 영역이 나옵니다 111 00:06:43.160 --> 00:06:46.760 여기가 이제 길이 되는 거예요 112 00:06:46.760 --> 00:06:49.810 그러면 이제 길이니까 이 길 위에 113 00:06:49.810 --> 00:06:53.250 저 AI 에너미가 이렇게 길 위에서 114 00:06:53.250 --> 00:06:55.620 이렇게 돌아서 올 수 있게 하면 되겠죠 115 00:06:55.620 --> 00:06:58.380 그래서 장애물을 조금 더 배치를 해볼까요? 길게 116 00:06:58.380 --> 00:07:02.200 이렇게 좀 더 넓히겠습니다 117 00:07:02.200 --> 00:07:07.080 이렇게 배치를 한 다음에 길을 찾게 만들면 되는데 118 00:07:07.080 --> 00:07:11.630 이번에는 에너미를 잠깐 볼게요 119 00:07:11.630 --> 00:07:17.240 에너미를 선택하고 에너미의 디테일 부분을 보시면 120 00:07:17.240 --> 00:07:21.190 쭉 내려보면 Pawn이라는 부분이 있습니다 여기 보면 121 00:07:21.190 --> 00:07:25.400 Pawn이 있는데요 Pawn을 보면 122 00:07:25.400 --> 00:07:30.700 여기 이렇게 되어있죠? 123 00:07:30.700 --> 00:07:33.990 AI Controller Class에 AIController라는 게 124 00:07:33.990 --> 00:07:36.300 이렇게 끼워져 있습니다 그렇죠? 그리고 125 00:07:36.300 --> 00:07:39.950 Auto Possess AI는 Placed in World라고 되어있어요 126 00:07:39.950 --> 00:07:41.700 이렇게 되어있으면 어떻게 되냐면 127 00:07:41.700 --> 00:07:45.740 기본적으로 이 녀석의 컨트롤러는 AIController입니다 128 00:07:45.740 --> 00:07:50.640 여러분 언리얼은 기본적으로 이런 개념이에요 129 00:07:50.640 --> 00:07:54.580 말판이죠 이렇게 월드가 있는데 이 월드에 130 00:07:54.580 --> 00:07:57.080 이런 캐릭터 같은 것들이 이렇게 있는 거죠 131 00:07:57.080 --> 00:07:59.100 Pawn이나 캐릭터들이 있고요 132 00:07:59.100 --> 00:08:01.900 그러면 사용자가 여기 있는 말 중에 133 00:08:01.900 --> 00:08:05.650 어떤 것을 잡고 움직일 것인가라는 형태로 이제 134 00:08:05.650 --> 00:08:07.250 제어를 한다고 보시면 돼요 135 00:08:07.250 --> 00:08:16.860 그래서 보통 Player Controller가 있고요 136 00:08:16.860 --> 00:08:19.310 이렇게 있고 그 다음에 137 00:08:19.310 --> 00:08:22.360 이거는 이제 입력을 받아서 입력값을 이렇게 넣어줘서 138 00:08:22.360 --> 00:08:24.440 그걸 제어할 수 있는 개념이 되는 거고 139 00:08:24.440 --> 00:08:26.840 이거 말고 길 찾기라든지 140 00:08:26.840 --> 00:08:34.440 이런 것들은 AIController라는 게 따로 있습니다 141 00:08:34.440 --> 00:08:39.040 이렇게 있고 그래서 AI도요 얘를 붙드는 거예요 142 00:08:39.040 --> 00:08:40.690 포제스하는 개념이 되는 거죠 143 00:08:40.690 --> 00:08:42.090 플레이어는 이걸로 포제스하고 있고 144 00:08:42.090 --> 00:08:43.840 이거는 AI가 포제스하고 있고 145 00:08:43.840 --> 00:08:47.380 이런 개념으로 이해하시면 됩니다 146 00:08:47.380 --> 00:08:50.260 그럼 기본적으로 이 녀석은 이렇게 되어있죠 아 그리고 147 00:08:50.260 --> 00:08:54.010 이 Auto Possess AI가 뭐냐면 여기 펼쳐보시면 이렇게 148 00:08:54.010 --> 00:08:57.230 두 가지가 있습니다 Spawned와 Placed in World 149 00:08:57.230 --> 00:08:59.760 이렇게 있고 이거는 이제 둘 다 할 수 있는 거죠 150 00:08:59.760 --> 00:09:05.160 이건 무슨 뜻이냐면 이 캐릭터를 레벨에 배치할 때 151 00:09:05.160 --> 00:09:07.710 이렇게 정적으로 우리가 이렇게 152 00:09:07.710 --> 00:09:10.220 드래그&드롭으로 이렇게 배치를 할 수도 있잖아요 153 00:09:10.220 --> 00:09:14.520 그런데 그게 아니라 스폰 액터를 통해서 154 00:09:14.520 --> 00:09:16.620 여기다가 레벨에 배치를 할 수도 있어요 155 00:09:16.620 --> 00:09:19.000 스폰을 시킬 수도 있다는 거죠 156 00:09:19.000 --> 00:09:22.600 그러면 스폰을 했을 때 이 컨트롤러를 157 00:09:22.600 --> 00:09:27.680 Possess AI, 포제스를 어떻게 할 것이냐라는 거예요 158 00:09:27.680 --> 00:09:30.490 그래서 여기 보면 이렇게 되어 있는데 159 00:09:30.490 --> 00:09:32.890 이렇게 하면 예를 들어서 여러분들이 에너미를 160 00:09:32.890 --> 00:09:35.320 생성하는 생성기를 만들었다고 해볼게요 161 00:09:35.320 --> 00:09:39.170 그러면 그 녀석은 AIController가 포제스 하지 않게 돼요 162 00:09:39.170 --> 00:09:42.870 왜냐하면 이거는 월드에 배치되어 있는 놈만 163 00:09:42.870 --> 00:09:45.170 자동으로 컨트롤러가 이렇게 164 00:09:45.170 --> 00:09:48.280 포제스를 하는 개념이기 때문이죠 165 00:09:48.280 --> 00:09:50.430 그래서 이거를 이렇게 바꿔주셔야 166 00:09:50.430 --> 00:09:53.530 나중에 여러분들이 에너미를 생성하는 걸로 만들었다 167 00:09:53.530 --> 00:09:57.730 그러면 에너미를 스폰시키면 자동으로 AIController가 168 00:09:57.730 --> 00:10:00.760 에너미를 포제스를 딱 해서 시작을 하게 됩니다 169 00:10:00.760 --> 00:10:05.220 이렇게 구성을 해주시면 되고요 170 00:10:05.220 --> 00:10:08.570 근데 우리는 에너미 생성기를 만들지는 않을 거예요 171 00:10:08.570 --> 00:10:10.770 그래서 한 마리만 할 거라서 사실 이거는 172 00:10:10.770 --> 00:10:13.370 크게 의미는 없지만 여러분들이 작업하시다 보면 173 00:10:13.370 --> 00:10:16.080 이것 때문에 좀 곤란을 겪을 수가 있습니다 174 00:10:16.080 --> 00:10:18.760 그래서 한번 말씀드렸고요 175 00:10:18.760 --> 00:10:24.120 보통 이렇게 해놓고 작업하시면 됩니다 176 00:10:24.120 --> 00:10:27.360 한번 저장해주고요 177 00:10:27.360 --> 00:10:30.760 그러면 에너미를 한번 이동을 시켜볼 건데요 178 00:10:30.760 --> 00:10:35.360 그러면 Move에서 처리를 해야겠죠 179 00:10:35.360 --> 00:10:39.210 그런데 아까 두 가지 조건이 있다고 했는데 180 00:10:39.210 --> 00:10:42.180 하나는 길이에요 길은 만들었죠 볼륨으로 181 00:10:42.180 --> 00:10:46.040 두 번째는 AIController를 가지고 진행을 해야 됩니다 182 00:10:46.040 --> 00:10:50.170 그래서 EnemyFSM에 보면 183 00:10:50.170 --> 00:10:52.800 AIController를 가지고 있지 않죠 184 00:10:52.800 --> 00:10:56.500 그래서 여기다가 AIController를 가지고 있도록 185 00:10:56.500 --> 00:10:58.060 변수를 하나 만들어줄게요 186 00:10:58.060 --> 00:11:02.760 UPROPERTY라고 하고요 187 00:11:02.760 --> 00:11:07.760 class AAIController 188 00:11:07.760 --> 00:11:10.710 이 컨트롤러들은 A로 시작합니다 189 00:11:10.710 --> 00:11:12.760 액터 형식으로 되어있어요 190 00:11:12.760 --> 00:11:15.760 플레이어 컨트롤러도 마찬가지입니다 A로 시작합니다 191 00:11:15.760 --> 00:11:23.140 이렇게 하고 AI라고 하겠습니다 192 00:11:23.140 --> 00:11:25.760 그러면 이 값을 채워야겠죠 193 00:11:25.760 --> 00:11:31.760 BeginPlay에서 채워주도록 할게요 194 00:11:31.760 --> 00:11:36.780 여기에서 AI는 Me에 있겠죠 Me가 가지고 있으니까요 195 00:11:36.780 --> 00:11:42.020 Me에 GetController 하시면 가지고 올 수 있고요 196 00:11:42.020 --> 00:11:44.760 이것을 캐스팅해서 사용하도록 할게요 197 00:11:44.760 --> 00:11:50.760 Cast라고 하고요 198 00:11:50.760 --> 00:11:59.400 여기는 AAIController가 되겠습니다 199 00:11:59.400 --> 00:12:01.550 그러면 이걸 가지고 왔으니까 200 00:12:01.550 --> 00:12:03.760 이걸 가지고 이동을 해볼 건데요 201 00:12:03.760 --> 00:12:11.760 TickMove로 가서 AI를 이용해서 이동해 볼 건데요 202 00:12:11.760 --> 00:12:16.760 여기 있는 Me에 AddMovementInput은 주석을 치시고 203 00:12:16.760 --> 00:12:19.760 그 다음에 AI를 가지고 이동을 하겠습니다 204 00:12:19.760 --> 00:12:23.260 AI에 보면 Move라고 검색해 보시면 205 00:12:23.260 --> 00:12:25.660 MoveTo 혹은 MoveToActor, Location 206 00:12:25.660 --> 00:12:29.560 이런 것들이 있습니다 이거를 사용하면 되고요 207 00:12:29.560 --> 00:12:37.760 저는 여기에서 MoveToLocation을 이용해 볼게요 208 00:12:37.760 --> 00:12:44.760 이 함수는요 여기에 보면 목적지를 넣게 되어 있죠 209 00:12:44.760 --> 00:12:46.130 그리고 이렇게 되어있는데 210 00:12:46.130 --> 00:12:48.760 이거를 보기가 좀 어려우니까 211 00:12:48.760 --> 00:12:51.760 블루프린트에서 한번 잠깐 보고 갈게요 212 00:12:51.760 --> 00:12:55.760 여기에서 AI MoveTo라고 하시면 213 00:12:55.760 --> 00:12:59.760 이런 것이 나오는데요 214 00:12:59.760 --> 00:13:05.760 여기 보면 목적지에 어떤 위치를 넣거나 215 00:13:05.760 --> 00:13:08.460 그 목적지에 해당하는 Target Actor를 넣으면 216 00:13:08.460 --> 00:13:10.060 그쪽으로 이동할 수 있고요 217 00:13:10.060 --> 00:13:14.430 그 다음에 이 Acceptance Radius는 218 00:13:14.430 --> 00:13:17.980 그 근처까지 가까이 가면 도착했다라는 219 00:13:17.980 --> 00:13:20.040 어떤 범위 값입니다 220 00:13:20.040 --> 00:13:23.060 그래서 예를 들어서 그런 거 있잖아요 221 00:13:23.060 --> 00:13:25.350 정확하게 그 포지션에 이 로케이션에 222 00:13:25.350 --> 00:13:27.740 딱 일치해야지 원래 도착한건데 223 00:13:27.740 --> 00:13:30.380 그렇게 하면 사실 정확하게 계산하기가 어렵죠 224 00:13:30.380 --> 00:13:32.760 그래서 좀 범위를 주는 거예요 225 00:13:32.760 --> 00:13:36.760 지금 보면 5cm로 되어있는데 그러면 조금 어렵거든요 226 00:13:36.760 --> 00:13:41.620 그래서 이거를 한 50cm 정도 이런 식으로 주면 되고요 227 00:13:41.620 --> 00:13:44.300 이거는 여러분들이 컨셉에 맞게 228 00:13:44.300 --> 00:13:46.020 적당한 값을 넣어주시면 됩니다 229 00:13:46.020 --> 00:13:48.980 그래서 도착하게 되면 여기에서 230 00:13:48.980 --> 00:13:51.760 이런 신호가 나오는 거죠 이렇게 생겼어요 231 00:13:51.760 --> 00:13:57.920 그래서 이거랑 비슷하게 여기도 값을 채워주면 되는데요 232 00:13:57.920 --> 00:14:02.980 여기 보시면 Dest.가, Destination이 들어가죠 233 00:14:02.980 --> 00:14:05.880 목적지가 들어가고 그 다음에 역시 마찬가지로 234 00:14:05.880 --> 00:14:08.720 AcceptanceRadius가 들어갑니다 235 00:14:08.720 --> 00:14:11.640 그 다음에 비슷하게 StopOnOverlap 236 00:14:11.640 --> 00:14:13.880 이런 게 들어가고, 그렇죠? 이렇게 되어있는데요 237 00:14:13.880 --> 00:14:15.610 여기에서 이제 채워줘야 될 것은 238 00:14:15.610 --> 00:14:18.760 가장 중요한 것은 이거죠 Destination, 목적지 239 00:14:18.760 --> 00:14:21.760 목적지는 사실 Target의 GetActorLocation입니다 240 00:14:21.760 --> 00:14:23.380 이게 목적지예요 241 00:14:23.380 --> 00:14:29.960 그래서 이거를 FVector로 일단 따로 가지고 있을게요 242 00:14:29.960 --> 00:14:34.560 destination이라고 하고 이렇게 가지고 있겠습니다 243 00:14:34.560 --> 00:14:38.760 그러면 이것을 direction을 이렇게 바꿔주고요 244 00:14:38.760 --> 00:14:44.760 그 다음에 destination을 여기다가 이렇게 넣어주겠다는 거죠 245 00:14:44.760 --> 00:14:47.410 그리고 적당히 이제 도착했나라고 처리할 때는 246 00:14:47.410 --> 00:14:51.160 예를 들어 50 이렇게 넣어주면 되고요 247 00:14:51.160 --> 00:14:54.610 그런데 이거를 사용하려면 248 00:14:54.610 --> 00:14:56.520 그냥은 사용할 수가 없습니다 249 00:14:56.520 --> 00:14:58.760 모듈을 추가를 해줘야 돼요 250 00:14:58.760 --> 00:15:02.600 그래서 여기에서 Build.cs 파일로 가서 251 00:15:02.600 --> 00:15:04.760 여기 기억나시죠? 모듈 추가하는 곳 252 00:15:04.760 --> 00:15:07.760 여기다가 이렇게 추가를 할 건데요 253 00:15:07.760 --> 00:15:09.960 두 개를 추가할 거예요 254 00:15:09.960 --> 00:15:13.110 그런데 이거도 한번 보면 좋을 것 같아요 255 00:15:13.110 --> 00:15:16.440 그러면 AIController니까 256 00:15:16.440 --> 00:15:22.380 한번 검색을 해볼까요? 257 00:15:22.380 --> 00:15:27.580 AIController를 보면 258 00:15:27.580 --> 00:15:31.940 이것은 AIModule이라는 것을 사용해야 됩니다 259 00:15:31.940 --> 00:15:34.420 그래서 이 모듈을 260 00:15:34.420 --> 00:15:36.760 여기다가 이렇게 추가를 해주겠습니다 261 00:15:36.760 --> 00:15:38.591 AIModule이라고 합니다 262 00:15:52.120 --> 00:15:56.020 그리고 이왕 하는 김에 한 가지 더 넣을게요 263 00:15:56.020 --> 00:15:58.260 여기 보시면 AIModule도 있는데 264 00:15:58.260 --> 00:16:03.880 우리가 길 찾기를 할 때는 265 00:16:04.530 --> 00:16:09.060 UNavigationSystemV1 이라는 게 있거든요 266 00:16:09.060 --> 00:16:10.760 이 클래스를 사용할 건데 267 00:16:10.760 --> 00:16:13.760 이것도 같이 모듈을 미리 추가해 놓겠습니다 268 00:16:13.760 --> 00:16:18.410 여기 보면 여기 모듈은 NavigationSystem이에요 269 00:16:18.410 --> 00:16:24.120 이거를 그대로 여기다가 이렇게 작성을 해주겠습니다 270 00:16:24.120 --> 00:16:27.520 그래서 AIModule과 NavigationSystem 271 00:16:27.520 --> 00:16:31.400 이렇게 두 가지 모듈을 추가를 하고요 272 00:16:31.400 --> 00:16:33.140 그리고 돌아오겠습니다 273 00:16:33.140 --> 00:16:35.200 이쪽으로 와서 이걸 사용할 거고요 274 00:16:35.200 --> 00:16:37.140 이거 헤더 추가를 해야겠죠 275 00:16:37.140 --> 00:16:38.740 여기에서 헤더는 이렇게 276 00:16:38.740 --> 00:16:46.760 AIController라는 헤더를 이렇게 추가를 해주시면 되고요 277 00:16:46.760 --> 00:16:53.760 이것도 보시면 이렇게 추가하면 되는 거죠 278 00:16:53.760 --> 00:16:56.400 이렇게요 279 00:16:56.400 --> 00:17:01.760 이렇게 추가하면 됩니다 280 00:17:01.760 --> 00:17:06.980 그리고 여기에서 만들었으니까 한번 실행을 해볼까요 281 00:17:06.980 --> 00:17:08.760 이제 진짜로 가는지 282 00:17:08.760 --> 00:17:11.480 여기에서 일단은 언리얼을 잠깐 끄고요 283 00:17:11.480 --> 00:17:15.760 이거는 필요 없으니까 삭제하겠습니다 284 00:17:15.760 --> 00:17:17.360 잠깐 꺼주고요 285 00:17:17.360 --> 00:17:19.951 여기에서 빌드를 한번 해볼게요 286 00:17:36.520 --> 00:17:38.934 다시 실행을 하고요 287 00:17:51.280 --> 00:17:55.180 그러면 에너미가 이제 저 장애물을 피해서 288 00:17:55.180 --> 00:17:57.760 주인공을 향해서 이동하는 것을 볼 수 있고요 289 00:17:57.760 --> 00:18:05.040 이렇게 도망가면 이렇게 잘 따라오게 됩니다 290 00:18:05.040 --> 00:18:07.490 이게 기본적으로 제공되는 291 00:18:07.490 --> 00:18:09.760 길 찾기 시스템이라고 보시면 돼요 292 00:18:09.760 --> 00:18:12.060 그래서 가장 핵심은 길을 만들고 293 00:18:12.060 --> 00:18:15.760 그리고 AIController를 이용해서 이동을 한다 294 00:18:15.760 --> 00:18:17.760 길을 찾아간다라고 보시면 됩니다 295 00:18:17.760 --> 00:18:20.760 길 찾기는 결국은 목적지를 향해서 가는 거니까요 296 00:18:20.760 --> 00:18:24.617 이렇게 destination의 개념을 넣어주시면 되고요 297 00:18:26.759 --> 00:18:30.579 Navigation Invoker를 이용한 길 찾기와 패트롤 기능 298 00:18:31.340 --> 00:18:38.980 그러면 이 기능을 활용해서 우리가 길 찾기를 하는데 299 00:18:38.980 --> 00:18:41.020 이런 개념을 만들 거예요 300 00:18:44.500 --> 00:18:49.760 보시면 이렇게 전체 길이 이렇게 있습니다 301 00:18:49.760 --> 00:18:53.760 이렇게 있는데 에너미가 이렇게 서 있어요 302 00:18:53.760 --> 00:18:55.760 그런데 이제 주인공은 여기 있죠 303 00:18:55.760 --> 00:19:01.500 그래서 에너미가 주인공을 감지할 수 있는 거리가 있고 304 00:19:01.500 --> 00:19:04.760 그 다음에 만약에 아무것도 감지를 못했을 수도 있잖아요 305 00:19:04.760 --> 00:19:07.970 그러면 자기가 임의의 점을 하나 찍어서 306 00:19:07.970 --> 00:19:09.900 그쪽으로 이동할 거에요 이렇게 이동하고 307 00:19:09.900 --> 00:19:15.760 여기 도착하면 다시 검색을 해서 또 다른 곳으로 가고 308 00:19:15.760 --> 00:19:18.940 그렇게 막 무작위로 랜덤으로 움직이다가 309 00:19:18.940 --> 00:19:24.660 만약에 에너미의 감지 범위 안에 310 00:19:24.660 --> 00:19:28.560 주인공이 이렇게 들어오게 된다면 311 00:19:28.560 --> 00:19:33.510 주인공이 이렇게 해서 이렇게 들어오게 된다면 312 00:19:33.510 --> 00:19:34.500 이렇게요 313 00:19:34.500 --> 00:19:38.420 그러면 기존에 가던 곳을 가는 것이 아니라 314 00:19:38.420 --> 00:19:42.340 에너미가 이쪽을 향해서 주인공을 향해서 이동하는 거죠 315 00:19:42.340 --> 00:19:44.760 그리고 주인공이 다시 도망갔어요 316 00:19:44.760 --> 00:19:47.500 이렇게 도망을 가서 멀어지게 되면 317 00:19:47.500 --> 00:19:49.180 일정 거리 이상 멀어지게 되면 318 00:19:49.180 --> 00:19:54.220 다시 원래 자기가 가던 곳으로 계속해서 순찰하는 개념 319 00:19:54.220 --> 00:19:58.620 그래서 순찰이라는 개념과 320 00:19:58.620 --> 00:20:01.420 그 다음에 추적이라는 개념을 만들고 싶습니다 321 00:20:01.420 --> 00:20:04.980 이걸 만들기 위해서는 방법은 여러가지가 있어요 322 00:20:04.980 --> 00:20:06.160 상태를 만들어도 돼요 323 00:20:06.160 --> 00:20:09.460 이동 상태에서 내가 순찰하거나 추적하거나 324 00:20:09.460 --> 00:20:11.080 이렇게 처리를 할 수도 있고요 325 00:20:11.080 --> 00:20:12.760 다양한 방법이 있는데 326 00:20:12.760 --> 00:20:16.260 언리얼에는 길에 대한 처리를 할 수 있는 방법이 327 00:20:16.260 --> 00:20:21.760 여러가지가 있는데 그 중에 인보커라는 게 있습니다 328 00:20:21.760 --> 00:20:25.760 인보커라는 게 있는데 인보커는 이런 개념이에요 329 00:20:25.760 --> 00:20:29.420 길이라는 게 굉장히 정적으로 만들어지는 거거든요 330 00:20:29.420 --> 00:20:31.760 처음에는, 무슨 말이냐면 331 00:20:31.760 --> 00:20:34.760 이렇게 엄청나게 큰 길이 있다고 해볼게요 332 00:20:34.760 --> 00:20:37.060 굉장히 큰 맵을 만들었는데 333 00:20:37.060 --> 00:20:39.260 거기에 길 정보를 만들었어요 334 00:20:39.260 --> 00:20:40.960 그러면 처음에 길 정보를 만드는데 335 00:20:40.960 --> 00:20:42.760 시간이 좀 많이 걸리겠죠 336 00:20:42.760 --> 00:20:46.760 그래서 이제 다 만들어졌으면 그 길 위에 337 00:20:46.760 --> 00:20:49.910 AI가 이렇게 있어서 거기를 이동을 하게 된다 338 00:20:49.910 --> 00:20:55.760 이런 개념인데 만약에 이게 오픈월드다 339 00:20:55.760 --> 00:20:57.760 이러면 좀 문제가 되겠죠 340 00:20:57.760 --> 00:21:01.760 왜냐하면 이 맵이 엄청나게 클 거 아닙니까? 341 00:21:01.760 --> 00:21:06.760 그러면 이 맵의 오픈월드에 대한 레벨을 수정할 때마다 342 00:21:06.760 --> 00:21:08.760 다시 길을 또 만들어야 되고 343 00:21:08.760 --> 00:21:10.760 그런 일을 해야 되는데 344 00:21:10.760 --> 00:21:13.760 그러면 부하가 걸릴 수 있고 345 00:21:13.760 --> 00:21:16.380 성능적인 이슈가 발생할 수가 있어요 346 00:21:16.380 --> 00:21:18.030 그래서 어떤 개념이 있냐면 347 00:21:18.030 --> 00:21:20.060 이 인보커라는 건 뭐냐면 348 00:21:20.060 --> 00:21:23.760 전체 길을 물론 정적으로 349 00:21:23.760 --> 00:21:26.760 그러니까 정적이라는 개념이 있고 350 00:21:26.760 --> 00:21:28.760 동적이라는 개념이 있어요 351 00:21:28.760 --> 00:21:31.760 정적이라는 건 미리 다 해놓는 거죠 352 00:21:31.760 --> 00:21:33.760 미리 만들어 놓는 것 353 00:21:38.440 --> 00:21:39.760 이걸 얘기하는 거고 354 00:21:39.760 --> 00:21:42.760 동적이라는 것은 그때그때 만드는 거죠 355 00:21:45.760 --> 00:21:46.940 그렇죠? 356 00:21:46.940 --> 00:21:48.760 그래서 인보커를 이용하면 이런 식으로 357 00:21:48.760 --> 00:21:51.760 그때그때 길을 만들어서 처리를 할 수가 있어요 358 00:21:51.760 --> 00:21:55.960 그러면 인보커에서는 길을 만들 때 어떻게 되냐면 359 00:21:55.960 --> 00:21:58.760 내가 이제 새로 검색할 영역이 있고 360 00:21:58.760 --> 00:22:00.760 그 다음에 이렇게 이동을 하잖아요 361 00:22:00.760 --> 00:22:03.120 그러면 길이 이미 있었을 거 아닙니까? 362 00:22:03.120 --> 00:22:05.760 그렇죠? 그럼 새롭게 이렇게 길을 만들어낼 건데 363 00:22:05.760 --> 00:22:08.760 그러면 기존에 있는 길은 범위를 벗어났잖아요 364 00:22:08.760 --> 00:22:11.520 그러면 이걸 삭제할 거예요 365 00:22:11.520 --> 00:22:13.760 그래서 동적으로 계속해서 만들어서 366 00:22:13.760 --> 00:22:17.400 자기 주변만 이렇게 길로 인식을 하는 그런 개념입니다 367 00:22:17.400 --> 00:22:20.260 그래서 멀리 있으면 길 위에 있는 것이 아니라 368 00:22:20.260 --> 00:22:22.760 자기의 인식 범위 밖에 있다고 이해해서 369 00:22:22.760 --> 00:22:24.760 길이 아닌 거죠 370 00:22:24.760 --> 00:22:28.760 이걸 이용하면 순찰, 추적 이런 것들을 할 수가 있겠죠 371 00:22:28.760 --> 00:22:31.760 실제로 거리를 측정해서 해도 되는데 372 00:22:31.760 --> 00:22:33.060 이런 식으로 인보커를 이용합니다 373 00:22:33.060 --> 00:22:34.760 NavigationInvoker라고 하는데 374 00:22:34.760 --> 00:22:37.760 이것을 이용해서 또 만들 수가 있어요 375 00:22:37.760 --> 00:22:41.760 그래서 이런 것들을 한번 학습을 해보려고 합니다 376 00:22:42.760 --> 00:22:46.640 이것을 처리하기 위해서 일단 인보커를 등록을 해줄 건데 377 00:22:46.640 --> 00:22:48.640 일단 에너미로 갈게요 378 00:22:48.640 --> 00:22:52.140 에너미에다가 이렇게 Add 컴포넌트를 하나 추가할 겁니다 379 00:22:52.140 --> 00:22:56.580 이렇게 해서 invoker라고 적어보세요 380 00:22:56.580 --> 00:23:01.520 NavigationInvoker라는 게 있습니다 381 00:23:01.520 --> 00:23:04.560 이렇게 추가하면 되는데 근데 이렇게 하면 나중에 또 382 00:23:04.560 --> 00:23:06.520 에너미를 새로 만들거나 그러면 383 00:23:06.520 --> 00:23:08.280 이게 없잖아요 그렇죠? 384 00:23:08.280 --> 00:23:13.430 그래서 이것은 코드로 생성해서 넣어주도록 하겠습니다 385 00:23:13.430 --> 00:23:18.240 여기 보시면 Navigation의 Generation Radius와 386 00:23:18.240 --> 00:23:20.200 Removal Radius 두 가지가 있어요 387 00:23:20.200 --> 00:23:21.120 이게 그것입니다 388 00:23:21.120 --> 00:23:23.760 이것은 새로 만드는 길의 영역이고 389 00:23:23.760 --> 00:23:26.760 이동한 후에 멀어졌잖아요 390 00:23:26.760 --> 00:23:28.760 그러면 이 정도까지 멀어졌으면 391 00:23:28.760 --> 00:23:31.760 기존의 그 부분에 대해서는 삭제하겠다 392 00:23:31.760 --> 00:23:33.760 이런 개념이라고 보시면 됩니다 393 00:23:39.600 --> 00:23:44.760 그래서 저는 이것을 한 500, 800 정도 394 00:23:44.760 --> 00:23:47.760 이렇게 배치를 하고 작업을 할 거거든요 395 00:23:47.760 --> 00:23:51.540 그러면 이것을 코드로 먼저 작성을 한 다음에 396 00:23:51.540 --> 00:23:54.140 그 다음에 다시 이어서 할게요 397 00:23:54.140 --> 00:23:57.760 에너미의 헤더 파일로 갑니다 398 00:23:57.760 --> 00:23:59.760 여기다 만들게요 399 00:24:02.410 --> 00:24:06.600 그래서 UPROPERTY 400 00:24:06.600 --> 00:24:09.160 (EditAnywhere)라고 하고요 401 00:24:09.160 --> 00:24:18.460 class UNavigationInvokerComponent 402 00:24:18.460 --> 00:24:20.340 이런 게 있습니다 403 00:24:20.340 --> 00:24:25.760 이거는 NavInvoker라고 할게요 404 00:24:25.760 --> 00:24:27.760 Comp라고 적어볼까요? 405 00:24:31.760 --> 00:24:33.760 이걸 생성해 주겠습니다 406 00:24:33.760 --> 00:24:37.060 그러면 Enemy의 생성자로 가서 407 00:24:37.060 --> 00:24:38.760 여기 있네요 바로 밑에다가 408 00:24:38.760 --> 00:24:40.760 이어서 작성하겠습니다 409 00:24:40.760 --> 00:24:44.760 인보커도 보시면 이렇게 점선이 있죠? 410 00:24:44.760 --> 00:24:46.760 여기 실선이 하나 있네요 411 00:24:46.760 --> 00:24:47.760 선 아래쪽에 있죠? 412 00:24:47.760 --> 00:24:50.760 여기 있는 것들은 액터 컴포넌트들이에요 413 00:24:50.760 --> 00:24:53.040 위에 있는 게 씬 컴포넌트들이고요 414 00:24:53.040 --> 00:24:54.360 그렇게 보시면 돼서 415 00:24:54.360 --> 00:24:58.760 이거는 밑에 있으니까 어태치 할 필요가 없죠 416 00:24:58.760 --> 00:25:01.750 여기에서 생성을 해 주겠습니다 417 00:25:01.750 --> 00:25:05.910 CreateDefaultSubobject라고 하고요 418 00:25:05.910 --> 00:25:11.360 여기는 UNavigationInvokerComponent 419 00:25:11.360 --> 00:25:13.760 이름을 지어주시고요 420 00:25:21.640 --> 00:25:24.760 그리고 여기에 값을 넣어주면 되겠죠? 421 00:25:24.760 --> 00:25:26.260 아까 전에 우리가 여기에 422 00:25:26.260 --> 00:25:29.240 Generation Radius와 Removal Radius 423 00:25:29.240 --> 00:25:31.800 이렇게 500, 800으로 줬습니다 424 00:25:31.800 --> 00:25:35.720 5m, 8m 이렇게 작성을 한 거고요 425 00:25:35.720 --> 00:25:37.720 이렇게 쓰고 426 00:25:42.340 --> 00:25:44.700 Generation Radius 427 00:25:44.700 --> 00:25:46.760 여기 있네요 428 00:25:51.760 --> 00:25:53.760 이렇게 넣어주면 되고요 429 00:25:53.760 --> 00:25:55.760 여기에 Generation Radius와 430 00:25:55.760 --> 00:25:58.400 Removal Radius를 작성을 해주면 됩니다 431 00:25:58.400 --> 00:26:03.010 500, 800 이렇게 적어주도록 하겠습니다 432 00:26:03.010 --> 00:26:07.760 그리고 이거는 헤더 추가를 해야겠죠? 433 00:26:07.760 --> 00:26:11.100 헤더는 이렇게 추가했고요 434 00:26:11.100 --> 00:26:13.760 이것도 이렇게 보면 435 00:26:20.220 --> 00:26:22.800 이렇게 넣어주시면 됩니다 436 00:26:31.320 --> 00:26:35.760 언리얼은 잠깐 껐다가 다시 컴파일해서 열겠습니다 437 00:26:48.920 --> 00:26:51.403 그러면 잘 반영되었는지 확인해 볼게요 438 00:26:51.403 --> 00:26:52.683 이거는 삭제를 하고요 439 00:26:52.683 --> 00:26:56.509 선택해보시면 여기 잘 되어있죠? 440 00:26:56.509 --> 00:27:00.460 그리고 이제 프로젝트 설정을 좀 해줘야 되는데요 441 00:27:00.460 --> 00:27:04.060 Edit의 Project Settings에 보시면 442 00:27:04.060 --> 00:27:08.200 여기에 쭉 내려보시면... 여기 있네요 443 00:27:08.200 --> 00:27:11.180 내비게이션 관련된 항목이 두 가지가 있습니다 444 00:27:11.180 --> 00:27:13.440 Mesh하고 System이 있는데요 445 00:27:13.440 --> 00:27:15.254 Navigation Mesh부터 보면 446 00:27:15.254 --> 00:27:18.729 좀 내려보시면 447 00:27:18.729 --> 00:27:21.394 여기 보면 Runtime에 448 00:27:21.394 --> 00:27:24.100 Generation을 어떻게 할 것인지가 적혀있는데요 449 00:27:24.100 --> 00:27:24.980 여기 Static으로 되어있습니다 450 00:27:24.980 --> 00:27:27.894 이게 아까 얘기한 길을 만들 때 451 00:27:27.894 --> 00:27:30.466 처음부터 만들어 놓고 시작한다는 뜻이에요 452 00:27:30.466 --> 00:27:32.266 근데 인보커를 사용한다는 것은 453 00:27:32.266 --> 00:27:34.226 실시간으로 만들 거기 때문에 454 00:27:34.226 --> 00:27:40.620 이것을 펼쳐서 Dynamic으로 교체해 주겠습니다 455 00:27:40.620 --> 00:27:43.560 그리고 이 Navigation System으로 오셔서 456 00:27:43.560 --> 00:27:47.080 여기 보시면 Navigation 457 00:27:47.080 --> 00:27:51.060 Invoker를 사용할지에 대한 체크박스가 있습니다 458 00:27:51.060 --> 00:27:53.180 이거를 체크를 해 주십시오 459 00:27:55.300 --> 00:27:57.440 이 두 가지 설정을 해주시면 되고요 460 00:27:57.440 --> 00:28:01.960 돌아와서 전체 저장을 한번 해주고요 461 00:28:01.960 --> 00:28:05.760 그러면 이제 이 사각형이 좀 달라졌죠 462 00:28:05.760 --> 00:28:07.760 아까는 전체가 다 길이였는데 463 00:28:07.760 --> 00:28:13.160 이번에는 에너미의 주변 부분만 이렇게 길이 되는 걸 볼 수 있습니다 464 00:28:13.160 --> 00:28:16.120 에너미를 조금 더 뒤로 밀고요 465 00:28:16.120 --> 00:28:19.080 그러면 여기만 이제 길인 거죠 466 00:28:19.080 --> 00:28:23.020 실행을 해보면 에너미가 제자리 걸음을 합니다 467 00:28:23.020 --> 00:28:24.840 주인공을 찾지를 못하죠 468 00:28:24.840 --> 00:28:27.220 가까이 가도 469 00:28:27.220 --> 00:28:28.760 가까이 가면 이제 찾아올 수 있고요 470 00:28:28.760 --> 00:28:33.760 멀리 떨어지면 이렇게 도망을 가보면 찾아올 수가 없습니다 471 00:28:33.760 --> 00:28:35.380 이걸 좀 원활히 하기 위해서 472 00:28:35.380 --> 00:28:39.040 에너미의 움직임의 크기를 주인공보다 좀 느리게 하겠습니다 473 00:28:39.040 --> 00:28:48.180 Enemy Character Movement의 Walk Speed를 한 400으로 좀 줄이겠습니다 474 00:28:48.180 --> 00:28:53.760 컴파일 하고요 그리고 475 00:28:57.300 --> 00:29:00.760 그러면 이거를 이제 구현을 해야겠죠 476 00:29:00.760 --> 00:29:05.360 EnemyFSM의 TickMove로 오셔서 477 00:29:05.360 --> 00:29:09.140 여기에다가 이제 작성을 해보겠습니다 478 00:29:09.140 --> 00:29:13.760 목적지를 검색하기 위해서 479 00:29:13.760 --> 00:29:20.760 먼저 경로를 탐색해야 되는데요 480 00:29:20.760 --> 00:29:25.160 탐색을 하기 위해서 481 00:29:25.160 --> 00:29:26.760 auto라고 하고요 482 00:29:26.760 --> 00:29:28.760 ns라고 할게요 이게 뭐냐면 483 00:29:28.760 --> 00:29:31.040 Navigation System을 얘기하는 거고요 484 00:29:31.040 --> 00:29:35.220 그래서 UNavigationSystemV1이라는 게 있어요 485 00:29:35.220 --> 00:29:43.760 이것에서 GetNavigationSystem을 가져오겠습니다 486 00:29:43.760 --> 00:29:44.980 여기에는 World가 들어가죠 487 00:29:44.980 --> 00:29:53.000 GetWorld 넣어주시면 되고요 488 00:29:53.000 --> 00:29:55.300 그리고 이거를 가지고 할 건데 489 00:29:55.300 --> 00:29:59.040 결론적으로 ns에 보면 490 00:29:59.040 --> 00:30:03.360 FindPath... Sync, Async 두 가지가 있어요 491 00:30:03.360 --> 00:30:05.140 Async는 비동기로 이제 하는 거고 492 00:30:05.140 --> 00:30:08.260 우리는 동기로 처리를 하겠습니다 493 00:30:08.260 --> 00:30:09.620 이렇게 Sync라고 하고요 494 00:30:09.620 --> 00:30:11.560 여기에 이제 값을 넣으면 되는데 495 00:30:11.560 --> 00:30:14.060 여기 보면 PathFindingQuery가 들어가고 496 00:30:14.060 --> 00:30:17.760 그 다음에 PathFindingMode가 들어가는데 497 00:30:17.760 --> 00:30:19.760 이거는 그냥 기본적으로 들어가니까요 498 00:30:19.760 --> 00:30:24.000 Query를 만들어줘야 될 필요가 있습니다 그래서 499 00:30:24.000 --> 00:30:30.420 FPathFindingQuery 500 00:30:30.420 --> 00:30:35.760 이 변수를 이렇게 만들어줄게요 501 00:30:35.760 --> 00:30:36.760 Query라고 하고요 502 00:30:36.760 --> 00:30:42.760 이거를 여기에 이렇게 넣어주시면 됩니다 503 00:30:42.760 --> 00:30:47.340 그 다음에 AI에 보면 504 00:30:47.340 --> 00:30:51.860 여기에는 BuildPathfinding 이런 게 있어요 505 00:30:51.860 --> 00:30:55.760 그래서 이걸로 길을 실제로 빌딩을 하는 거거든요 506 00:30:55.760 --> 00:30:59.840 이렇게 해서 여기에는 이제 4개 변수가 507 00:30:59.840 --> 00:31:05.160 FAIMoveRequest 여기 들어가고 508 00:31:05.160 --> 00:31:06.760 그 다음에 Query가 들어갑니다 509 00:31:06.760 --> 00:31:10.760 그래서 FAIMoveRequest 510 00:31:10.760 --> 00:31:12.760 변수가 또 하나 있어야겠죠 511 00:31:12.760 --> 00:31:15.760 이거는 req라고 할게요 512 00:31:15.760 --> 00:31:17.760 Request에는 요청이니까 513 00:31:17.760 --> 00:31:20.760 뭐가 들어가냐면 AcceptanceRadius가 들어갑니다 514 00:31:20.760 --> 00:31:25.140 아까 전에 우리 50으로 넣으면 될 것 같아요 이렇게 515 00:31:25.140 --> 00:31:28.760 이거는 이제 근처 50cm까지 근처에 오면 516 00:31:28.760 --> 00:31:31.760 도착했다 이런 식의 처리니까요 517 00:31:31.760 --> 00:31:33.760 그 다음에 요청할 때 518 00:31:33.760 --> 00:31:36.220 목적지를 넣어야겠죠 여기에 519 00:31:36.220 --> 00:31:39.240 SetGoalLocation 이렇게 해서 520 00:31:39.240 --> 00:31:46.360 destination을 이렇게 넣어주도록 하겠습니다 521 00:31:46.360 --> 00:31:49.760 그리고 이것을 여기다가 넣으면 되는데요 522 00:31:49.760 --> 00:31:51.260 여기에 req를 넣고 523 00:31:51.260 --> 00:31:56.760 그 다음에 query를 이렇게 넣어주시면 되겠죠 524 00:31:56.760 --> 00:31:59.960 그러면 req를 통해서 525 00:31:59.960 --> 00:32:07.760 query가 채워지는 그러한 형태가 되고요 526 00:32:07.760 --> 00:32:10.760 이거 사용하시면 이런거 다 헤더를 추가하셔야 돼요 527 00:32:10.760 --> 00:32:14.740 저는 위에 추가가 되어 있는 것 같아요 528 00:32:14.740 --> 00:32:16.320 이렇게 추가되어 있는데 529 00:32:16.320 --> 00:32:19.640 이렇게 Navigation System도 추가를 해주십시오 530 00:32:21.620 --> 00:32:24.274 여기 검색해보시면 이렇게 531 00:32:30.977 --> 00:32:33.090 이렇게 해서 여기 이 내용을 532 00:32:33.090 --> 00:32:36.583 저 상단에다가 헤더 추가를 해주시면 되겠습니다 533 00:32:42.760 --> 00:32:47.850 이렇게 하면 일단 길을 찾았습니다 그러면 534 00:32:51.750 --> 00:32:54.300 이것을 가지고 뭔가 처리를 해야겠죠 535 00:32:54.300 --> 00:32:56.440 이거에 이제 반환값이 있어요 536 00:32:56.440 --> 00:32:59.860 여기 보면 FPathFindingResult라는 게 있는데요 537 00:32:59.860 --> 00:33:03.140 이걸 받을게요 538 00:33:03.140 --> 00:33:06.500 auto r 이렇게 받겠습니다 539 00:33:06.500 --> 00:33:11.000 그리고 만약에 이것이 성공했다면 540 00:33:11.000 --> 00:33:14.300 아 r이 아니죠 r에 Result가 있습니다 541 00:33:14.300 --> 00:33:15.960 이겁니다 이걸로 해야되고 542 00:33:15.960 --> 00:33:17.760 == 하면 되고요 543 00:33:17.760 --> 00:33:21.760 이거는 이제 ENavigationQueryResult에요 544 00:33:21.760 --> 00:33:23.940 그러면 이거거든요 545 00:33:23.940 --> 00:33:27.760 여기에서 보면 546 00:33:27.760 --> 00:33:29.400 성공 실패 이런 것들이 나와요 547 00:33:29.400 --> 00:33:31.500 성공했을 때만, 어떻게 해요? 548 00:33:31.500 --> 00:33:34.760 이때는 추적이죠 549 00:33:34.760 --> 00:33:38.140 여기에서는 이제 destination을 향해서 가는 거니까 550 00:33:38.140 --> 00:33:40.760 이 destination은 여기 보면 551 00:33:40.760 --> 00:33:42.760 Target의 Location입니다 그렇죠? 552 00:33:42.760 --> 00:33:44.760 그래서 목적지가 553 00:33:44.760 --> 00:33:46.820 우리가 에너미 입장이니까 554 00:33:46.820 --> 00:33:48.760 플레이어를 목적지로 했다면 555 00:33:48.760 --> 00:33:50.620 이제 쭉 가면 되는 거고요 그쪽으로 556 00:33:50.620 --> 00:33:52.620 그래서 기존에 구현했던 내용이 557 00:33:52.620 --> 00:33:54.960 여기에 추적으로 들어가면 되고요 558 00:33:54.960 --> 00:34:00.080 근데 인보커는 현재 전체 길에서 559 00:34:00.080 --> 00:34:02.960 자기 영역만 딱 체크하는 거잖아요 560 00:34:02.960 --> 00:34:05.360 그러니까 길 밖에 있을 수도 있는 거죠 561 00:34:05.360 --> 00:34:08.940 else인 경우에는 562 00:34:08.940 --> 00:34:11.920 목적지가 여기가 아닌 거죠 563 00:34:11.920 --> 00:34:14.040 여기가 아니라 랜덤한 위치를 넣고 싶어요 564 00:34:14.040 --> 00:34:15.860 그래서 RandomLocation 565 00:34:15.860 --> 00:34:17.900 목적지를 기억을 하고 있어야겠죠? 566 00:34:17.900 --> 00:34:21.420 그래서 변수를 하나 기억하고 있겠습니다 567 00:34:21.420 --> 00:34:27.880 그러면 RandomLocation 568 00:34:27.900 --> 00:34:31.860 이렇게 변수를 하나 만들어줄게요 569 00:34:31.860 --> 00:34:34.000 그러면 이 일을 먼저 해야겠죠 570 00:34:34.000 --> 00:34:40.400 이걸 쓰려면 랜덤한 위치를 만들기 위해서 571 00:34:40.400 --> 00:34:43.760 여기 헤더에다가 선언을 해줄게요 572 00:34:43.760 --> 00:34:44.960 제일 아래쪽에다가 할까요? 573 00:34:44.960 --> 00:34:50.380 이렇게 해서 FVector로 574 00:34:50.380 --> 00:34:51.760 RandomLocation 575 00:34:51.760 --> 00:34:53.240 이렇게 기억하고 있을 거고 576 00:34:53.240 --> 00:34:56.480 그럼 이것을 채우는 일을 해야겠죠 577 00:34:56.480 --> 00:34:59.000 채우기 위해서 함수를 하나 만들건데 578 00:34:59.000 --> 00:35:02.280 bool 타입으로 할 거고요 579 00:35:02.280 --> 00:35:06.460 GetRandomLocation 580 00:35:06.460 --> 00:35:07.760 이라는 함수를 만들까요 581 00:35:07.760 --> 00:35:12.940 InNavMesh 582 00:35:12.940 --> 00:35:15.760 이렇게 해주겠습니다 583 00:35:15.760 --> 00:35:18.010 그럼 첫번째 인자는 원점이에요 584 00:35:18.010 --> 00:35:20.730 원점에서부터 얼마의 반경 안에 585 00:35:20.730 --> 00:35:22.620 하나의 점을 찍을 거니까요 586 00:35:22.620 --> 00:35:26.920 그래서 FVector origin 587 00:35:26.920 --> 00:35:27.940 이렇게 할 거고요 588 00:35:27.940 --> 00:35:35.260 그 다음에 float radius 589 00:35:35.260 --> 00:35:38.000 그리고 결과를 반환 590 00:35:38.000 --> 00:35:39.900 여기 리턴 값이 bool이니까 591 00:35:39.900 --> 00:35:42.180 그러면 실제로 어떤 값을 넣어서 592 00:35:42.180 --> 00:35:43.600 여기에서 채워주면 좋을 것 같아요 그래서 593 00:35:43.600 --> 00:35:50.800 FVector& 이렇게 해서 Out 594 00:35:50.800 --> 00:35:54.640 결과 리턴 값을 여기다가 받겠습니다 595 00:35:54.640 --> 00:35:58.540 OutLocation 596 00:35:58.540 --> 00:36:01.940 이런 식으로 변수를 만들어줄게요 597 00:36:01.940 --> 00:36:03.760 이렇게 변수를 선언을 해주고 598 00:36:03.760 --> 00:36:08.320 그 다음에 이걸 구현부로 만들겠습니다 599 00:36:08.320 --> 00:36:11.880 이렇게 만들고요 600 00:36:11.880 --> 00:36:14.220 여기도 이제 Navigation System이 필요해요 601 00:36:14.220 --> 00:36:16.660 그래서 auto ns라고 하고요 602 00:36:16.660 --> 00:36:20.077 UNavigationSystemV1에서 603 00:36:20.077 --> 00:36:25.440 GetNavigationSystem 604 00:36:25.440 --> 00:36:31.940 가지고 오도록 하겠습니다 GetWorld로 605 00:36:31.940 --> 00:36:35.760 그럼 ns에 보면 606 00:36:35.760 --> 00:36:38.340 random 607 00:36:38.340 --> 00:36:47.754 GetRandom 하시면 608 00:36:47.760 --> 00:36:50.360 보시면 이렇게 함수가 있어요 609 00:36:50.360 --> 00:36:52.360 포인트 같은 경우에는 610 00:36:52.360 --> 00:36:55.540 GetRandomPointInNavigableRadius 611 00:36:55.540 --> 00:36:59.760 이거는 전체 길에서 랜덤 값을 612 00:36:59.760 --> 00:37:01.360 탁 찍는 거고요 613 00:37:01.360 --> 00:37:05.040 Reachable은 내가 이동할 수 있는 위치 614 00:37:05.040 --> 00:37:08.280 랜덤 지역 중에서 이동할 수 있는 615 00:37:08.280 --> 00:37:09.760 위치를 의미한다고 보시면 돼요 616 00:37:09.760 --> 00:37:12.180 그래서 이걸로 가져오도록 하겠습니다 617 00:37:12.180 --> 00:37:14.140 이렇게 하고 618 00:37:14.140 --> 00:37:16.840 매개변수가 인자값을 뭘 넣어야되냐 보면 619 00:37:16.840 --> 00:37:18.080 여기 origin이 들어가죠 620 00:37:18.080 --> 00:37:21.280 origin 넣어주시고요 621 00:37:21.280 --> 00:37:23.460 그 다음에 radius가 들어가요 622 00:37:23.460 --> 00:37:26.210 반지름이 들어가고 그 다음에 623 00:37:26.210 --> 00:37:29.200 FNavLocation & 해서 624 00:37:29.200 --> 00:37:31.240 이런 변수를 하나 넣어줘야 됩니다 625 00:37:31.240 --> 00:37:34.560 그럼 여기에 결과를 이렇게 담아주는 방식이죠 626 00:37:34.560 --> 00:37:41.760 그래서 FNavLocation 이렇게 해주고요 627 00:37:46.980 --> 00:37:49.760 이거를 로케이션이라고 할까요? 628 00:37:49.760 --> 00:37:51.760 이렇게 넣어주도록 하겠습니다 629 00:37:51.760 --> 00:37:53.760 그러면 여기에 실제로 담기겠죠 630 00:37:53.760 --> 00:37:56.760 그리고 이것은 bool을 반환해요 631 00:37:56.760 --> 00:37:58.660 성공, 실패가 있다는 거죠 632 00:37:58.660 --> 00:38:00.420 그래서 그것을 받겠습니다 633 00:38:00.420 --> 00:38:05.380 bool bResult = 이렇게 받을게요 634 00:38:07.760 --> 00:38:11.180 그리고 이걸 반환할 거고요 635 00:38:11.180 --> 00:38:15.000 그리고 만약에 결과가 참이면 636 00:38:15.000 --> 00:38:17.760 성공했으면 그때 637 00:38:17.760 --> 00:38:21.260 OutLoc에다가 여기에서 담아온 638 00:38:21.260 --> 00:38:24.580 로케이션 값이 있죠 이거를 639 00:38:24.580 --> 00:38:28.120 이렇게 담아주도록 하겠습니다 640 00:38:28.120 --> 00:38:30.180 이러한 함수를 하나 만들면 되고요 641 00:38:30.180 --> 00:38:33.300 이 함수는 처음에 시작할 때 642 00:38:33.300 --> 00:38:37.440 BeginPlay에서 643 00:38:37.440 --> 00:38:40.760 여기에서 랜덤 위치를 하나 정하고 갈 거예요 644 00:38:40.760 --> 00:38:46.240 이렇게 해서 origin이니까 GetActor 645 00:38:46.240 --> 00:38:49.760 이거는 지금 컴포넌트니까요 646 00:38:49.760 --> 00:38:51.760 여기에서는 Me에서 가져오면 되겠네요 647 00:38:51.760 --> 00:38:55.760 Me의 GetActorLocation 648 00:38:55.760 --> 00:38:57.000 이렇게 가져오고요 649 00:38:57.000 --> 00:38:59.220 반지름은 500이라고 넣겠습니다 650 00:38:59.220 --> 00:39:02.800 한 5m정도 651 00:39:02.800 --> 00:39:04.620 그리고 이제 결과를 넣어야 되는데 652 00:39:04.620 --> 00:39:06.280 여기는 랜덤 로케이션을 넣어주겠습니다 653 00:39:06.280 --> 00:39:07.760 그러면 여기에 채워지겠죠 654 00:39:07.760 --> 00:39:09.760 RandomLocation에 655 00:39:09.760 --> 00:39:12.960 이렇게 생긴 함수를 이용해서 656 00:39:12.960 --> 00:39:14.880 이 값을 채울거고요 657 00:39:14.880 --> 00:39:17.260 그러면 이렇게 채워놓고 다시 658 00:39:17.260 --> 00:39:19.760 TickMove 쪽으로 이동해서 659 00:39:19.760 --> 00:39:22.220 이걸 이어서 구현해줄 건데 660 00:39:22.220 --> 00:39:24.160 그러면 여기에서 이렇게 할 거고 661 00:39:24.160 --> 00:39:26.460 여기에서는 이제 662 00:39:26.460 --> 00:39:34.180 일단은 랜덤 위치로 이동하고요 663 00:39:34.180 --> 00:39:38.800 만약에 도착하거나 664 00:39:38.800 --> 00:39:40.240 그 위치에 문제가 있다면 665 00:39:40.240 --> 00:39:43.100 다시 랜덤 위치를 정해야 되잖아요 666 00:39:43.100 --> 00:39:47.340 위치에 문제가 있다면 667 00:39:47.340 --> 00:39:51.280 다시 랜덤 위치를 정하고 싶다 668 00:39:51.280 --> 00:39:52.680 이런 일을 하고 싶어요 669 00:39:52.680 --> 00:39:54.980 그래서 제가 여기 복사해서 가져왔고요 670 00:39:54.980 --> 00:39:58.120 이동을 하는데 결과를 봐야겠죠 671 00:39:58.120 --> 00:40:02.660 도착했는지를 알려면 결과를 알아야 되니까요 672 00:40:02.660 --> 00:40:04.880 결과를 알기 위해서는 이렇게 할 수 있습니다 673 00:40:04.880 --> 00:40:08.040 실제로 MoveToLocation은 반환값이 있어요 674 00:40:08.040 --> 00:40:10.420 그래서 이 반환값을 가지고 675 00:40:10.420 --> 00:40:12.640 결과를 알 수가 있겠죠 676 00:40:12.640 --> 00:40:16.100 auto라고 하고요 677 00:40:16.100 --> 00:40:17.440 이건 patrol이죠 678 00:40:17.440 --> 00:40:20.800 patrolResult 679 00:40:20.800 --> 00:40:23.560 이렇게 받을게요 680 00:40:23.560 --> 00:40:26.700 어 그런데 Set이 빠졌네요 여기 보니까 681 00:40:26.700 --> 00:40:29.080 Set 이렇게 넣어주겠습니다 682 00:40:29.080 --> 00:40:32.240 그 다음에 patrolResult를 받았으니까 683 00:40:32.240 --> 00:40:34.340 이걸 가지고 비교를 해보면 되겠죠 684 00:40:34.340 --> 00:40:37.360 만약에 도착했다면 685 00:40:37.360 --> 00:40:41.760 patrolResult == 해서 686 00:40:41.760 --> 00:40:44.200 이렇게 해서 EPathFollowingRequestResult 687 00:40:44.200 --> 00:40:48.120 여기에 보면 AlreadyAtGoal이라는 게 있습니다 688 00:40:48.120 --> 00:40:51.260 그러면 이게 도착했다면이라는 거고 689 00:40:51.260 --> 00:40:53.760 혹은 그 위치에 문제가 있다면 690 00:40:53.760 --> 00:40:56.900 둘 중에 하나라도 참이라면 이 일을 하겠다는 거예요 691 00:40:56.900 --> 00:40:59.120 랜덤한 위치를 정하는 일을 692 00:40:59.120 --> 00:41:03.020 그래서 이렇게 구성을 할 거고요 693 00:41:03.020 --> 00:41:05.520 여기다가 or 해가지고 694 00:41:05.520 --> 00:41:09.760 한 가지 더 조건을 달게요 695 00:41:09.760 --> 00:41:12.920 이 조건은 Failed라면 696 00:41:12.920 --> 00:41:16.420 실패했다면, 실패했어도 뭔가 못 가잖아요 697 00:41:16.420 --> 00:41:20.360 그러니까 더 이상 갈 수 없는 상황이라면 698 00:41:20.360 --> 00:41:23.180 도착했거나 문제가 생겨서 699 00:41:23.180 --> 00:41:25.220 갈 수가 없는 상황이라면 700 00:41:25.220 --> 00:41:28.120 다시 랜덤한 위치로 목적지를 정하겠다 701 00:41:28.120 --> 00:41:30.280 이런 뜻이 됩니다 702 00:41:30.280 --> 00:41:34.480 이렇게 해서 한번 빌드를 해볼게요 703 00:41:37.960 --> 00:41:39.220 실패를 했는데요 704 00:41:39.220 --> 00:41:41.320 지금 이걸 사용하려면 705 00:41:41.320 --> 00:41:43.760 헤더를 추가를 해야 될 것 같습니다 706 00:41:43.760 --> 00:41:45.760 그래서 이쪽으로 와서 707 00:41:52.340 --> 00:41:54.700 헤더를 추가하겠습니다 708 00:41:57.600 --> 00:42:00.280 추가를 하고 빌드를 다시 해볼게요 709 00:42:02.220 --> 00:42:04.220 네 이제 성공했죠 710 00:42:07.560 --> 00:42:10.420 이런 구성을 하면 되고요 711 00:42:10.670 --> 00:42:13.760 언리얼을 실행해서 잘 동작하는지 볼게요 712 00:42:32.104 --> 00:42:34.304 여기 키보드에서 실행 중에는 713 00:42:34.304 --> 00:42:36.890 Enter 왼쪽에 있는 따옴표 있죠? 714 00:42:36.890 --> 00:42:38.740 그걸 누르면 이렇게 나오거든요 715 00:42:38.740 --> 00:42:40.980 저기 파란색으로 보이는 부분이 716 00:42:40.980 --> 00:42:43.460 실제로 길 영역이라고 보시면 됩니다 717 00:42:43.460 --> 00:42:45.100 에너미가 움직이면서 718 00:42:45.100 --> 00:42:48.460 저 길 영역 안에 랜덤한 위치 하나를 잡는 거예요 719 00:42:48.460 --> 00:42:50.760 그리고 제가 가까이 가면 720 00:42:50.760 --> 00:42:53.760 이제 제가 길 위에 있으니까 저한테 오죠 721 00:42:53.760 --> 00:42:56.300 그리고 도망을 가볼게요 722 00:42:56.300 --> 00:42:57.940 도망을 이렇게 가면 723 00:42:57.940 --> 00:42:59.940 거리가 멀어지면 이제 저한테 오지 않고 724 00:42:59.940 --> 00:43:02.160 다시 랜덤한 위치를 찍어서 725 00:43:02.160 --> 00:43:05.760 그쪽으로 이동을 하는 형태가 되는 걸 볼 수 있습니다 726 00:43:08.640 --> 00:43:12.220 도착하고 공격하고 다시 도망가면 727 00:43:12.220 --> 00:43:13.680 이렇게 쫓아오고 728 00:43:13.680 --> 00:43:15.320 혹은 패트롤 하고 729 00:43:15.320 --> 00:43:18.280 이런 식으로 처리가 되고요 730 00:43:20.400 --> 00:43:22.040 문제가 뭐냐면 731 00:43:25.020 --> 00:43:25.760 이런 문제가 있습니다 732 00:43:25.760 --> 00:43:27.620 가까이 오고 있을 때 탕 쏘면 733 00:43:27.620 --> 00:43:30.140 미끄러지면서 저한테 와요 그렇죠? 734 00:43:30.140 --> 00:43:32.420 이거를 좀 해결을 해줄 건데요 735 00:43:35.860 --> 00:43:37.380 지금 총에 맞았다 736 00:43:37.380 --> 00:43:38.680 상태가 있습니다 그렇죠? 737 00:43:38.680 --> 00:43:41.480 그러면 여기에 상태들을 처리하는 곳이 있는데 738 00:43:41.480 --> 00:43:45.980 Damage인 경우 혹은 Die인 경우 739 00:43:45.980 --> 00:43:48.680 그리고 공격하는 중 이런 경우에는 740 00:43:48.680 --> 00:43:52.380 길을 이렇게 Move를 하면 안 되죠 741 00:43:52.400 --> 00:43:54.520 그래서 이 세 경우 742 00:43:54.520 --> 00:43:56.140 Idle도 마찬가지인데요 743 00:43:56.140 --> 00:43:58.320 TickMove일 때만 실제로 744 00:43:58.320 --> 00:44:01.540 AI가 길을 찾는 일을 활성화하고 745 00:44:01.540 --> 00:44:05.700 나머지 상태에서는 멈춰야 될 것 같습니다 746 00:44:05.700 --> 00:44:07.760 그래서 그걸 처리를 해줄 건데 747 00:44:07.760 --> 00:44:11.380 이거 일일이 다 끼워넣으면 좀 너무 애매하고 748 00:44:11.380 --> 00:44:13.760 어디다가 작업할지 어려우니까요 749 00:44:13.760 --> 00:44:16.760 기본적으로 우리가 상태를 전환하는 750 00:44:16.760 --> 00:44:18.640 SetState 함수가 있습니다 751 00:44:18.640 --> 00:44:26.360 여기에서 만약에 newState가 752 00:44:26.360 --> 00:44:31.940 MoveState가 아니라면 753 00:44:31.940 --> 00:44:35.160 AI를 멈추고 싶다 754 00:44:35.160 --> 00:44:38.920 이렇게 한번 처리를 해보죠 755 00:44:38.920 --> 00:44:42.500 그럼 여기에서 간단하게 조건문을 이렇게 걸고요 756 00:44:42.500 --> 00:44:49.180 newState가 Move라면 757 00:44:49.180 --> 00:44:50.320 이게 아니죠 758 00:44:50.320 --> 00:44:55.760 newState가 이렇게 해서 759 00:44:55.760 --> 00:44:57.280 Move가 아니라면이니까 760 00:44:57.280 --> 00:45:00.040 여기에다가 느낌표를 이렇게 넣어주시면 되겠죠 761 00:45:00.040 --> 00:45:04.660 Move가 아니라면 AI를 stop하고 싶어요 762 00:45:04.660 --> 00:45:08.540 자 StopMovement라는 함수가 있습니다 763 00:45:08.540 --> 00:45:10.460 이렇게 멈춰버리고 싶다는 거죠 764 00:45:13.860 --> 00:45:17.300 다시 이것을 저장하고 765 00:45:17.300 --> 00:45:19.760 결과를 볼게요 컴파일하고 766 00:45:26.960 --> 00:45:30.060 가까이 가고요 767 00:45:30.060 --> 00:45:32.400 탕 하면 제자리 멈추죠 768 00:45:32.400 --> 00:45:33.940 다시 오고요 769 00:45:33.940 --> 00:45:37.760 공격하면서도 탕 하면 잘 죽습니다 770 00:45:41.300 --> 00:45:44.880 이번 단원에서 학습한 내용을 정리하도록 하겠습니다 771 00:45:45.675 --> 00:45:49.075 내비게이션 시스템을 이용한 길 찾기 길 찾기 시스템 AIModule, NavigationSystem 모듈을 추가함 레벨에 NavMeshBoundsVolume을 배치함 772 00:45:49.075 --> 00:45:52.492 Brush Setting의 X값과 Y값을 바닥을 다 덮을 수 있게 설정해 길을 만듦 AIController로 에너미가 길을 찾아가게 설정함 773 00:45:52.492 --> 00:45:53.592 Navigaton Invoker를 이용한 길 찾기와 패트롤 기능 길 찾기 정적으로 길을 만들 때 레벨에 배치된 맵의 크기가 너무 크면 성능 이슈가 생김 774 00:45:53.592 --> 00:45:54.792 Navigation Invoker 기능을 이용해 길을 동적으로 생성해 해결함 775 00:45:54.792 --> 00:45:55.942 ProjectSettings의 Navigation 관련 메뉴에서 길을 동적으로 생성하게 하고 Navigation Invoker 기능을 활성화함 776 00:45:55.942 --> 00:45:57.192 Project Settings에서 Navigation Mesh를 Dynamic으로 설정함 777 00:45:57.192 --> 00:45:58.392 Project Settings에서 Navigation System을 Navigation Invoker를 사용함으로 체크함 778 00:45:58.392 --> 00:45:59.342 패트롤 기능 추가하기 UNavigationSystemV1 클래스를 활용함 779 00:45:59.342 --> 00:46:00.312 목적지가 현재 길 위에 있다면 그곳으로 이동하고, 그렇지 않다면 랜덤으로 목적지를 정해서 이동함