의존성 주입 이제 가고일 석상을 트리거 박스 내에 두면 비밀문이 작동하도록 해야 한다. 이를 위해서는 우리가 만들었던 컴포넌트인 무버와 트리거 사이를 연결해주어야 할 필요가 있다. 이를 위해 필요한 것이 의존성 주입 기법이며, 다른 오브젝트가 필요하지만 직접 찾을 수 없는 경우에 사용된다. 해당 케이스의 경우에는 트리거 컴포넌트가 어디에서 무버를 찾을 수 있는지 블루프린트가 알려주어야 한다. 따라서 트리거 내에 무버를 세팅하는 함수를 BlueprintCallable로 선언한다. Mover를 사용하기 위해 헤더에 Move.h를 포함해주는 것도 잊으면 안된다. 다음으로 Mover를 세팅하는 함수를 구현해준다. 이때 주의해야 할 것이 인풋 파리미터의 이름과 클래스 변수의 이름이 동일하면 안된다. 만약 동일한 ..
얼리 리턴 Tick 함수에 구현한 액터 태그가 붙은 액터를 찾는 기능을 함수로 따로 빼준다. 안에서 값이 변경될 필요가 없으므로 const를 붙여주었다. 여기서 Grabber.cpp 에서 사용한 적이 있던 얼리 리턴을 사용해준다. 해당 함수가 반환하는 값은 액터 포인터이므로, 만약 태그에 붙은 액터가 존재한다면 바로 리턴을 해준다. 하지만 반복문이 모두 마친 후에 액터가 없을 수도 있기에, 이를 위해 기본적으로 리턴은 널포인터를 리턴하도록 해준다. 따라서 기본은 널포인터를 반환하지만, 만약 액터가 있다면 액터를 반환하게 되는 것이다. 이제 간단한 로그메시지로, Tick 함수에서 액터 태그가 붙은 액터가 있다면 Unlocking을, 액터가 없다면 다시 잠기므로 Relocking을 표시해보자. 직전에 만든 ..
액터 태그우리는 오버랩된 모든 것들을 원하는 것이 아니라, 오직 가고일 석상만을 이용하여 비밀문을 열고 싶다.이를 위해 사용되는 것이 액터 태그이다. Unlock1이라는 이름을 가진 태그를 만들고, 액터를 순회하면서 해당 태그를 가진 액터에 대해서만 로그을 출력해주도록 해보자.ActorHasTag 함수를 이용하여 우리가 설정한 Unlock1이라는 태그가 있을 때 로그메시지를 출력하도록 하였다. 이번엔 트리거를 여러 곳에 사용할 수 있도록, 트리거에 접근가능한 태그를 만들어보자.기존의 Unlock1이라는 문자열을 직접 넣어준 것과 달리, 편집가능한 AcceptableActorTag를 만들어주었다.이는 우리가 만든 트리거 컴포넌트에 존재하며, 언리얼에서 원하는 문자열을 작성하여 원하는 태그로 작성할 수 있..
범위 기반 For 반복문 배열 내 모든 값을 순회하는 방식은 상당히 자주 쓰이는 방식이다. 따라서 C++에는 이를 위한 특수한 형태의 반복문 또한 존재한다. 기존 for 문에서 인덱스 변수를 사용한 방식마록, 순회할 배열의 엘리먼트를 가리키는 포인터를 이용하여 순회가 가능하다. 우리가 순회하고자하는 것은 Actors에 대한 내용이므로, AActor* Actor의 값이 필요하며, 순회할 내용으로 Actors를 사용하게 된다. 전에 인덱스를 이용해 값을 가리켰던 것은 간단하게 Actor로 대체된다. 플레이시 기존과 똑같이 작동하는 것을 볼 수 있다.
While 및 For 반복문 저번 강의를 통해 오버랩된 액터들을 얻어 트리거 박스 내에 들어오는 액터의 이름을 출력해주었다. 하지만 플레이어와 가고일 조각상 둘 모두 들어가 있다면 어떻게 될까? 원하는 것은 둘 모두의 이름이 출력되는 것이지만, 실제로는 처음 출력된 한 가지만 계속 출력된다. 이를 고치기 위해 반복문을 사용한다. 반복문은 크게 2가지로 while문과 for문이 존재한다. 먼저 while문의 경우를 살펴보자. 처음 선언한 idx를 기준으로, 해당 값이 액터의 갯수보다 작으면 아래과정을 반복한다. 기존에 액터에 접근하기 위해 Actors[0]을 사용하였지만, 여기서는 idx가 인덱스를 나타내므로 idx를 사용한다. 마지막 줄에 idx를 증가시켜 다음 인덱스를 가리키도록 해준다. 액터의 총 갯..
TArray 트리거 박스에는 가고일 석상만 들어갈 수도 있지만, 사람이 실수로 들어갈 수도 있다. 따라서 오버랩된 것이 무엇인지 알 필요가 있으며, GetOverlappingActoros 함수를 통해 이를 알 수 있다. 함수를 살펴보면 TArray를 사용한다. 이는 배열의 일종이며, 사이에 어떤 타입의 값을 저장할지 명시하게 된다. 우리는 오버랩된 액터를 찾기에 AActor*를 작성하게 된다. 그리고 보면 해당 함수는 리턴 ㄱ밧이 없고, 오버랩된 액터에 대해 참조표시가 있는 것을 볼 수 있다. 이를 통해 오버랩된 액터들에 대한 파라미터가 아웃 파라미터인 것을 추정할 수 있다. 두 번째 값에 대해서는 디폴트로 설정되어있으므로 신경쓰지 않아도 된다. 이제 간단하게 오버랩된 액터들을 위해 먼저 TArray를 ..
생성자 새로 만든 TrigerrComponent cpp 파일에는 첫 플레이시 log 메시지를 추가하는 내용밖에 없다. 우리는 플레이 중 오버랩이 이루어지는 지 체크가 필요하므로 Tick 함수도 구현을 해주어야 한다. 여기서 Super를 작성한 부분도 빼먹으면 안된다. 이는 상위 클래스 기능을 호출해주는 것이며, 여기서는 박스 컴포넌트를 뜻 한다. 구현 기능을 위해 상위 클래스의 기능이 필요한 경우도 있기에 써주는 것이 필요하다. Tick에는 테스트로 간단한 로그 메시지를 써놓고 플레이 해보자. 하지만 현 상태로 Tick에 대한 메시지가 나오지 않는다. 이는 최적화의 측면에서 보통 Tick이 컴포넌트에서는 비활성화되어있기 때문이다. (액터 디폴트는 활성) 여기서 사용할 수 있는 것이 생성자이다. UMove..
오버랩 이벤트 우리가 설치한 비밀문에 가고일 석상이 들어간다면 이를 알릴 트리거 박스를 설치해보자. 이를 위해선 각 오브젝트가 가지는 콜리전 타입에 대해서 알아야 한다. 우리는 이를 이미 가고일 석상을 통해 확인을 한 적이 있다. 가고일의 오브젝트 타입은 WorldStatic이고, 다른 WorldStatic이나 WorldDynamic 타입들에 대해서는 차단되는 것을 볼 수 있다. 하지만 Pawn과는 오버랩인 상태이다. 이번엔 pawn을 살펴보자. 가고일의 타입인 WorldStatic타입에 대해 차단된 모습을 볼 수 있다. 이렇게 한 쪽은 오버랩 상태인데, 한 쪽은 차단된 상태이다. 이러면 어떻게 될까? 아래 표를 살펴보자. 표의 A를 Pawn으로, B를 가고일 석상으로 두고 생각해보자. A가 Block일..
아웃 파라미터 리턴 현재 Grab() 함수는 내용이 많아 이번에 함수 2개로 분리해주는 리팩토링 작업을 해준다. 함수로 뺄 부분에 해당하는 기능은 구체를 생성하고, Hit 반응이 있는지 없는지 체크해주는 부분이다. Hit 반응이 있는지 없는지가 핵심이기에 해당 함수 타입은 bool로 선언해준다. 함수 내부에서 값을 바꿀 일은 없기에 const를 사용해준다. 또한 HitResult를 입력받아야 하므로 이를 참조를 통한 아웃 매개 변수로 사용한다. 이제 해당 함수를 구현해줄 차례이다. 기존 내용을 우선 복사해오고, 기존 HitResult의 부분을 OutHitResult로 대체해준다. 또한 기존에 bool HasHit을 선언하고 해당 HasHit을 반환했지만, 여기서 바로 return 하여 해당 타입을 반환하..
물리 오브젝트 깨우기 지금 무사히 가고일 석상을 집을 수 있는 것처럼 보이지만, 플레이 일정 시간이 지난 후에 가고일 석상을 집으면 집을 수 없는 현상이 발생할 수 있다. 이는 물리 시뮬레이션 컴포넌트가 성능 상의 이유로 일정 시간 동안 가동되지 않으면 슬립 상태로 들어가기 때문에 발생하는 현상이다. 따라서 구체 트레이스로 히트했을 때 깨어나도록 만들어주어야 한다. 이를 위해 PrimitiveComponent에 대해 조금 더 자세히 알아야 할 필요가 있다. 공식 문서의 설명을 보면, 해당 컴포넌트는 씬 컴포넌트이자 특정 지오메트리를 포함하거나 생성하고 콜리전 데이터로 렌더링되거나 사용된다는 것을 알 수 있다. 이는 해당 컴포넌트가 물리 시뮬레이션을 수행한다는 뜻이다. 해당 컴포넌트가 사용 가능한 함수를 ..
PhysicsHandle로 객체 잡기 이제 위치도 알았으니, 진짜로 PhysicsHandle를 이용해 가고일 석상을 잡아볼 차례이다. 우선 PhysicsHandle이 없을 경우 성립자체가 불가능하므로 얼리리턴을 통해 바로 종료하도록 해준다. 다음으로 저번에 잠깐봤었던 GrabComponentAtLocationWithRotation 함수를 채워나갈 차례이다. 해당 함수가 필요한 항목은 다음과 같다. 처음 변수인 UPrimitiveComponent 타입을 어떻게 얻을 수 있을까? HitResult에 속한 함수를 찾아보면 다음과 같은 내용을 찾을 수 있다. HitResult에 속한 함수인 GetComponent 함수를 이용하면 우리가 찾는 UPrimitiveComponent를 얻을 수 있다. 따라서 HitRe..
DrawDebugSphere() 이제 GrabComponentAtLocationWithRotation() 함수를 이용하여 실제로 잡아볼 차례이다. 하지만 해당 함수에 위치를 넣어주는 부분이 다소 까다롭다. 단순히 실제 컴포넌트의 위치를 사용하는 것이 아니기 때문이다. 예시를 들자면, 우리는 가고일의 머리부분을 잡고자한다. 하지만 가고일의 실제 본질은 바닥 부분에 존재하여, 우리가 머리부분을 잡는다면 바닥~머리 부분만큼 위로 더 떠오른 상태로 집게되는 현상이 발생한다. 그래서 구체 트레이스를 할 때 가고일 석상과 만나는 부분을 찾아야한다. 이를 위해 DrawDebugSphere함수를 통해서 닿는 부분을 시각화하여 체크를 해줄 필요가 있다. 해당 함수의 헤더는 DrawDebugLine 함수를 사용할 때 썼던..
FindComponentByClass() & nullptr Grab 기능을 블루프린트로 가져왔지만, 실제로 잡는 것이 아니라 단순 로그메시지만 출력하고 있다. 물체를 잡으려면 물리 시스템과 상호작용을 해야하는데, 여기서 사용되는 것이 PhyscisHandle 컴포넌트이다. BP_Player에서 직접 추가가 가능하다. 이제 PhysicsHandle 컴포넌트를 Grabber 컴포넌트에서 얻을 방법을 알아야한다. 우선 PhysicsHadnle 컴포넌트를 사용하기 위해 헤더부터 선언해준다. 이제 FindComponentByClass 함수를 통해 PhysicsHandle 컴포넌트를 얻는 것이 가능하다. 해당 함수는 템플릿 함수로 여태 봤던 함수와 사뭇 다른 형태를 가지고 있다. 템플릿 함수는 컴파일 할 때 실제로..
블루프린트 호출 간단히 Grab에 대해 문자열을 출력하도록 했지만, 우리가 원하는 것은 우리가 C++에서 구현했던 기능이다. 이 기능을 블루프린트로 호출해줄 필요가 있다. 이를 위해 사용되는 것이 UFUNCTION이다. 테스트로 Release에 대한 함수를 만들어보자. 기존에는 문자열로 출력해줬지만, 이번엔 로그메시지로 출력하도록 함수로 구현해준다. 이제 BP_Player로 돌아가서 기존 print string을 해당 함수로 대체해주자. Grabber 컴포넌트를 끌어와서 해당 컴포넌트를 얻고, 여기서 함수를 가져오면 된다. 주의할 점은 라이브코딩으로 우리가 만든 Release 함수가 보이지 않을 수도 있다. 이 경우에는 에디터를 끄고, Vscdoe에서 제대로 컴파일을 해준 후에 다시 켜야할 필요가 있다...
인풋 동작 매핑 트레이스가 가능한 상태가 되었지만, 현재 트레이스가 아무때나 계속하여 실행되는 모습을 볼 수 있다. 우리가 원하는 것은 가고일을 집어 드는 것이기 때문에, 가고일을 집는 순간만 트레이스되는 것을 원한다. 따라서 인풋 동작 매핑에 집는 것을 추가해줄 필요가 있다. 이는 프로젝트 세팅 -> 입력 칸에서 가능하다. 액션 매핑과 축 매핑이 존재한다. 간단하게 말해서 액션 매핑은 마우스나 키보드를 누르는 액션, 축 매핑은 마우스를 돌리는 회전과 같은 것이다. 우리는 마우스 클릭을 이용해 집을 것이므로 액션 매핑을 추가해주면 된다. 여기서 작은 빨간색 박스로 표시한 부분을 누르고 왼쪽 마우스 버튼을 누르면 우측에 있는 칸이 해당 버튼으로 입력된다. 따라서 원하는 마우스 버튼이나 키보드 키를 간단하게..