이번 섹션의 목표는 탱크 게임을 만드는 것이다.플레이어가 조종할 수 있는 탱크를 만들고, 탱크를 움직이며 발사체를 발사하여 적 포탑을 부수게 된다.적 포탑 또한 탱크를 공격할 수 있으며, 서로의 HP가 먼저 0이 되는 쪽이 승리하게 된다. 기본적인 탱크 움직임을 위한 액션 매핑 및 축 매핑이나, 사운드를 위한 에셋등은 강의자료로 올라와있다.따라서 해당 강의자료를 다운로드하여 사용하게 되는데 나는 4.25버전을 다운로드하여 내가 사용중인 엔진 버전인 5.3으로 실행하였다. 폰 클래스 생성우선 우리는 탱크와 포탑이 필요하다.이를 위해 베이스폰 클래스를 생성해주고, 동일한 기능(발사체 발사)을 가진 탱크와 포탑 자식 클래스를 생성할 수 있다.C++ 클래스를 생성하게 되며, 이때 부모 클래스를..
문제링크 : https://www.acmicpc.net/problem/2012 2012번: 등수 매기기 첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 500,000) 둘째 줄부터 N개의 줄에 걸쳐 각 사람의 예상 등수가 순서대로 주어진다. 예상 등수는 500,000 이하의 자연수이다. www.acmicpc.net #include using namespace std; typedef long long ll; typedef pair pii; const int MAX = INT_MAX; int N, arr[500001]; ll result; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N; for(int i=1; i> arr[i]; sort(..
Crypt Raider: 마무리 이번 섹션을 통해 알아본 것은 다음과 같다. 액터 컴포넌트와 씬 컴포넌트 루멘 시스템 모듈식 레벨 디자인 라인 트레이싱 및 콜리전 헤더 파일 추가 C++ 포인터 및 레퍼런스 반복문 및 배열 블루프린트에서 C++ 호출 전에 배웠던 것들을 토대로, 좀 더 심화된 내용들을 다루게 된 섹션이다. 이번 섹션에서 배웠던 것중 집는 기능이 가장 기억에 남는데, 집는 것이 상당히 복잡한 과정을 거치는 것에 다소 놀라웠다. 처음 생각한 것은 단순히 그냥 눈에 보이는 사물을 집는 것이라고만 생각했다. 하지만 집는 사람이 누구인지, 무엇을 집을 것인지, 특히 집는 것이 어디있는지 찾는 과정이 존재했다. 집는 것이 어디있는지 찾는 과정인 라인 트레이싱이 가장 색다른 느낌을 받았음과 동시에 가장..

레벨 다듬기 이제 게임의 마무리 단계이다. 우리는 영묘에서 보물 조각상을 가져가야 하는데, 만약 보물 조각상을 가져가려하면 창살이 내려와 나가는 문이 닫힌다. 이를 위해 대신할 물건을 가져와 단상에 두어야 한다. 이 부분들을 이제 구현하게 된다. 먼저 대영묘에 단상과 조각상을 비치해주자. 기본적인 조각상의 크기가 매우 작아서 스케일을 조정해주어야 한다. 그런데 이후에 씬이 점점 어두워지는 모습을 볼 수 있다. 이는 씬의 노출 보정 메소드 때문에 벌어지는 현상이다. 포스트 프로세스 볼륨의 노출 칸에 있는 미터링 모드를 변경함으로서 해결이 가능하다. 해당 볼륨은 사실 작은 크기의 블록 형태로, 해당 블록 내에서만 방금 설정한 기능이 작동하게 된다. 우리가 만든 레벨 전체에 적용하기 위해서는 블록의 크기를 키..

불리언(Boolean) 논리 연산자 저번에 만든 액터 태그를 이용하여, 실제 구현을 해줄 차례이다. 이를 위해서는 우선 접근가능한 액터있는지 확인하고, 다음으로 해당 액터가 잡힌 상태인지를 알아야한다. 2가지에 대해 체크를 해주어야하므로, 여기서 불리언 논리 연산자를 사용하게 된다. 접근 가능한 액터를 찾는 함수에서 수정을 하게 되는데, 기존 if문에서 접근 가능한 액터가 있을 시 바로 액터를 반환해준 부분을 수정해주면된다. 먼저 접근 가능한 액터가 있는 지 체크해주고, 잡지 않은 액터인지도 이어서 체크해준다. 위 케이스의 경우 And 연산이기에 && 기호를 사용하였다. 만약 Or 연산을 하게된다면 || 기호를 사용하게 된다. 이러한 불리언 논리 연산자를 사용하여 if 문이 여러개인 것을 하나로 묶어 주..
문제링크 : https://www.acmicpc.net/problem/16435 16435번: 스네이크버드 첫 번째 줄에 과일의 개수 N (1 ≤ N ≤ 1,000) 과 스네이크버드의 초기 길이 정수 L (1 ≤ L ≤ 10,000) 이 주어집니다. 두 번째 줄에는 정수 h1, h2, ..., hN (1 ≤ hi ≤ 10,000) 이 주어집니다. www.acmicpc.net #include using namespace std; typedef long long ll; typedef pair pii; const int MAX = INT_MAX; int N, L, arr[10001]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> L; ..

태그 추가 및 삭제 드디어 비밀문이 제대로 작동하는 것처럼 보이지만, 아직 문제가 남아있다. 바로 잡고 있는 가고일 조각상을 놓지도 않았는데 비밀문이 작동해버리는 것이다. 이를 위해 잡았을 때와 놓았을 때를 알기 위한 태그를 추가해주는 작업이 필요하다. 먼저 잡았다는 내용의 태그를 추가해주자. 간단하게 Tags.Add를 통해 원하는 이름의 태그를 추가하는 것이 가능하다. 플레이를 해보면 가고일 조각상을 잡을 때 새롭게 "Grabbed" 태그가 생긴 것을 볼 수 있다. 이제 놓는 내용의 태그를 추가해주자. 액터를 얻기 위해 GetOwner()를 사용해줄 필요가 있다. 놓는 경우는 기존에 잡았던 "Grabbed" 태그를 지워주는 경우이다. 따라서 Tags.Remove를 통해 해당 태그를 지우게 된다. 집고 ..

캐스팅과 액터 부착 가고일 석상이 트리거 박스 내에 고정시키기 위해서는 가고일 석상을 트리거 박스에 부착시켜서 고정시켜줄 필요가 있다. 이를 위해 액터를 부착시키는 것 이외에도 부착 이후 가고일 석상의 물리 시뮬레이트를 false로 바꿔주어야 한다. 먼저 부착을 위해서 다음 함수를 사용한다. 그리고 물리 시뮬레이트 비활성화를 위해서는 다음 함수를 사용한다. 이제 구현을 해보는데, 먼저 가고일 석상의 루트 컴포넌트를 얻어야 한다. 이를 위해 기존 트리거 cpp 내에서 선언했던 Actor를 사용할 수 있고, GetRootComponent 함수를 사용하여 루트 컴포넌트를 얻을 수 있다. 하지만 여기서 문제가 생긴다. GetRootComponent 함수가 반환하는 컴포넌트는 UScene 컴포넌트이지만, SetS..

의존성 주입 이제 가고일 석상을 트리거 박스 내에 두면 비밀문이 작동하도록 해야 한다. 이를 위해서는 우리가 만들었던 컴포넌트인 무버와 트리거 사이를 연결해주어야 할 필요가 있다. 이를 위해 필요한 것이 의존성 주입 기법이며, 다른 오브젝트가 필요하지만 직접 찾을 수 없는 경우에 사용된다. 해당 케이스의 경우에는 트리거 컴포넌트가 어디에서 무버를 찾을 수 있는지 블루프린트가 알려주어야 한다. 따라서 트리거 내에 무버를 세팅하는 함수를 BlueprintCallable로 선언한다. Mover를 사용하기 위해 헤더에 Move.h를 포함해주는 것도 잊으면 안된다. 다음으로 Mover를 세팅하는 함수를 구현해준다. 이때 주의해야 할 것이 인풋 파리미터의 이름과 클래스 변수의 이름이 동일하면 안된다. 만약 동일한 ..
문제링크 : https://www.acmicpc.net/problem/15665 15665번: N과 M (11) 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해 www.acmicpc.net #include using namespace std; typedef long long ll; typedef pair pii; const int MAX = INT_MAX; int N, M, arr[8], result[8]; void func(int cnt) { if(cnt == M) { for(int i=0; i

얼리 리턴 Tick 함수에 구현한 액터 태그가 붙은 액터를 찾는 기능을 함수로 따로 빼준다. 안에서 값이 변경될 필요가 없으므로 const를 붙여주었다. 여기서 Grabber.cpp 에서 사용한 적이 있던 얼리 리턴을 사용해준다. 해당 함수가 반환하는 값은 액터 포인터이므로, 만약 태그에 붙은 액터가 존재한다면 바로 리턴을 해준다. 하지만 반복문이 모두 마친 후에 액터가 없을 수도 있기에, 이를 위해 기본적으로 리턴은 널포인터를 리턴하도록 해준다. 따라서 기본은 널포인터를 반환하지만, 만약 액터가 있다면 액터를 반환하게 되는 것이다. 이제 간단한 로그메시지로, Tick 함수에서 액터 태그가 붙은 액터가 있다면 Unlocking을, 액터가 없다면 다시 잠기므로 Relocking을 표시해보자. 직전에 만든 ..

액터 태그우리는 오버랩된 모든 것들을 원하는 것이 아니라, 오직 가고일 석상만을 이용하여 비밀문을 열고 싶다.이를 위해 사용되는 것이 액터 태그이다. Unlock1이라는 이름을 가진 태그를 만들고, 액터를 순회하면서 해당 태그를 가진 액터에 대해서만 로그을 출력해주도록 해보자.ActorHasTag 함수를 이용하여 우리가 설정한 Unlock1이라는 태그가 있을 때 로그메시지를 출력하도록 하였다. 이번엔 트리거를 여러 곳에 사용할 수 있도록, 트리거에 접근가능한 태그를 만들어보자.기존의 Unlock1이라는 문자열을 직접 넣어준 것과 달리, 편집가능한 AcceptableActorTag를 만들어주었다.이는 우리가 만든 트리거 컴포넌트에 존재하며, 언리얼에서 원하는 문자열을 작성하여 원하는 태그로 작성할 수 있..
문제링크 : https://www.acmicpc.net/problem/5568 5568번: 카드 놓기 예제 1의 경우 상근이는 11, 12, 21, 112, 121, 122, 212를 만들 수 있다. www.acmicpc.net #include using namespace std; typedef long long ll; typedef pair pii; const int MAX = INT_MAX; int N, K, arr[11]; bool check[11]; setresult; void func(int cnt, string s) { if(cnt == K) { result.insert(stoi(s)); //중복제거 return; } for(int i=0; i> N >> K; for(int i=0; i> ar..

범위 기반 For 반복문 배열 내 모든 값을 순회하는 방식은 상당히 자주 쓰이는 방식이다. 따라서 C++에는 이를 위한 특수한 형태의 반복문 또한 존재한다. 기존 for 문에서 인덱스 변수를 사용한 방식마록, 순회할 배열의 엘리먼트를 가리키는 포인터를 이용하여 순회가 가능하다. 우리가 순회하고자하는 것은 Actors에 대한 내용이므로, AActor* Actor의 값이 필요하며, 순회할 내용으로 Actors를 사용하게 된다. 전에 인덱스를 이용해 값을 가리켰던 것은 간단하게 Actor로 대체된다. 플레이시 기존과 똑같이 작동하는 것을 볼 수 있다.

While 및 For 반복문 저번 강의를 통해 오버랩된 액터들을 얻어 트리거 박스 내에 들어오는 액터의 이름을 출력해주었다. 하지만 플레이어와 가고일 조각상 둘 모두 들어가 있다면 어떻게 될까? 원하는 것은 둘 모두의 이름이 출력되는 것이지만, 실제로는 처음 출력된 한 가지만 계속 출력된다. 이를 고치기 위해 반복문을 사용한다. 반복문은 크게 2가지로 while문과 for문이 존재한다. 먼저 while문의 경우를 살펴보자. 처음 선언한 idx를 기준으로, 해당 값이 액터의 갯수보다 작으면 아래과정을 반복한다. 기존에 액터에 접근하기 위해 Actors[0]을 사용하였지만, 여기서는 idx가 인덱스를 나타내므로 idx를 사용한다. 마지막 줄에 idx를 증가시켜 다음 인덱스를 가리키도록 해준다. 액터의 총 갯..