
이전시간에 이어서 직접 해보기 항목을 진행해 보자
언리얼5-22 C++ <Cpp 튜토리얼 -변수, 타이머, 이벤트(1)>
변수, 타이머, 이벤트 | 언리얼엔진 문서(unrealengine.com)
첫 번째로 직접 만들어볼 과제로 이벤트가 실행되면 액터를 이동 또는 회전시키고, 일정 타이머가 끝나면 다시 원래 위치나 회전으로 되돌리는 2차 이벤트를 발동시키는 것이다 [게임에서 이동 플랫폼이나 문으로 사용할 수 있는 방식이다]
메뉴바에서 [Tools > New C++ Class..]를 눌러 Actor 클래스를 상속받아서 Door라는 이름으로 C++클래스를 만들어준다
클래스가 생성되고 나면 헤더 파일로 이동해서 몇 가지 변수들을 선언해 준다
문 모델링 메시를 가질 UStaticMeshComponent* 타입의 DoorMesh 변수,
문이 열렸다가 닫히는 시간을 표시할 float 타입의 CloseTime 변수,
문이 열리고 닫히는 과정을 표현하는데 사용할 float 타입의 DoorDeltaTime 변수,
문이 열린 상태인지 표현할 bool 타입의 bOpen 변수,
타이머를 관리하는데 쓰일 FTimerHandle 타입의 DoorTimerHandle 변수,
마지막으로 문의 원래 상태를 저장하고 있을 FRotator 타입의 OriginRotation 변수이다
이 중에서 DoorMesh와 CloseTime은 에디터의 디테일 패널에서 보고 변경할 수 있도록 UPROPERTY 매크로를 붙이고 EditAnywhere 지정자를 넣어준다
그리고 문을 열고 닫는 동작을 구현할 Open 함수와 Close 함수 역시 선언해 준다
그다음에는 cpp 파일의 ADoor 생성자로 이동한다
생성자에서는 CreateDefaultSubobject 함수로 DoorMesh에 UStaticMeshComponent를 추가해서 넣어주고 이 컴포넌트를 Root Component로 만들어 준 후 CloseTime의 기본 값을 3초로 초기화해 준다
그다음에는 BeginPlay 함수로 이동해서 OriginRotation에 게임이 시작할 당시의 액터의 회전 상태를 저장해 두고, SetTimer 함수로 Door 클래스의 Open 함수를 0.03초의 간격으로 반복해서 호출하도록 만들어준다
Tick 함수에서는 DoorDeltaTime 변수에 Tick 함수의 매개변수로 받아오는 DeltaTime을 계속 더해주도록 코드를 작성한다
이제 Open 함수를 작성할 차례이다
Open 함수에서는 bOpen이 아닌 상태, 즉 문이 열리지 않은 상태라면 열린 상태로 변경하고 DoorDeltaTime을 0으로 만들어준다
그리고 액터의 회전 상태를 가져와서 DoorDeltaTime 값의 상태에 따라서 열린 상태로 문을 회전시키고,
CloseTime이 지난 후 DoorDeltaTime의 값이 1보다 크면 현재 작동 중인 타이머를 멈춘 다음 문을 닫도록 만든다
그다음 Close 함수에서는 Open 함수와 거의 비슷하지만 몇 가지 동작을 반대로 작성하고 DoorDeltaTime이 1이 되어서 문이 닫히는 동작이 끝나면 타이머를 중단시키기만 하면 된다
코드를 모두 작성하면 저장하고 에디터로 돌아가서 컴파일한다
컴파일이 끝난 다음에는 레벨에 Door C++ 클래스를 배치하고 디테일 패널에서 DoorMesh 컴포넌트를 선택한 다음, StaticMesh 프로퍼티에 SM_Door 스태틱 메시 에셋을 찾아서 할당해 준다
그다음 게임을 플레이시켜 보면 시작되자마자 문이 열렸다가 잠시 후에 닫히는 모습을 볼 수 있는 것이 아니라 돌고 있다
다시 코드를 살펴보니 rotation을 구할 때 처음에 구해둔 OriginRotation을 사용해야 하는데 그냥 rotation을 사용한 것이다
이 rotation들을 OriginRotation으로 변경한다
그리고 코드를 저장하고 에디터로 돌아가서 다시 컴파일하고 게임을 실행한다
이제 정상적으로 동작하는 것을 볼 수 있다
이제 두 번째 직접 해보기 과제를 해보자
두 번째 과제의 내용은 이벤트와 타이머를 이용해서 불타는 파티클이 꺼지도록 만들라는 것이다
기본적인 요구 사항은 별다른 동작이 없으면 연소 시간 동안 타오르다가 꺼지는 것이고, 특정한 이벤트가 발생하면 연소 시간에 관계없이 바로 꺼지도록 만드는 것이다. 그리고 Tick 함수를 사용하지 않는 제약이 있다
우선 Actor 클래스를 상속받는 Fire라는 이름의 C++ 클래스를 생성한다
클래스 생성이 끝나면 헤더로 가서 UParticleSystemComponent* 타입의 FireParticle 변수와 int8 타입의 FireTime 변수, 그리고 FTimerHandle 타입의 FireTimerHandle을 선언해 준다
FireParticle과 FireTime도 에디터에 공개되게 만들기 위해서 UPROPERTY 매크로를 붙이고 EditAnywhere 지정자를 넣어준다
그리고 불 파티클이 연소시간 동안 타들어가게 하는 Combustion 함수와 이벤트가 실행되면 연소시간을 0으로 만들고 파티클을 꺼지게 만드는 OffFire 함수를 선언해 준다 (OffFire 함수는 블루프린트에서 호출할 수 있게 UFUNCTION 매크로에 BlueprintCallable 지정자를 넣어준다)
그다음에는 cpp 파일 ParticleSystemComponent를 사용하기 위해 #include "Particles/ParticleSystemComponent.h"를 선언해 준다
AFire 생성자에서는 CreateDefaultSubobject 함수로 FireParticle에 UParticleSystemComponent를 추가해서 넣어주고 이 컴포넌트를 Root Component로 만들어 주는 코드를 작성한다. FireTime의 기본 값은 5초로 초기화해 준다
그다음 BeginPlay 함수에서는 SetTimer 함수를 이용해서 Combustion 함수를 1초마다 한 번씩 호출하게 만들어준다
그리고 Combustion 함수에서는 한 번 호출될 때마다 FireTime을 1씩 줄여주고 FireTime이 0이 되면 OffFire 함수를 호출하게 만들어준다
마지막으로 Offire 함수에서는 타이머를 중단시키고 FireParticle을 비활성화시키는 코드를 작성해 준다
코드를 작성하고 나면 모두 저장하고 에디터로 돌아가서 컴파일해 준다
컴파일이 끝나면 Fire C++ 클래스를 레벨에 배치하고 디테일 패널의 FireParticle 컴포넌트를 선택한 후에 P_Fire 파티클을 찾아서 넣어준다
그리고 게임을 플레이시켜보면 FireTime = 5; 와 Combustion( )함수에 의해 5초 후 불 파티클이 꺼지는 것을 볼 수 있다
이제 여기서 특정한 키를 누르면 이 불 파티클이 연소 시간에 관계없이 바로 꺼지게 만들어보자
Fire을 선택 후 디테일 패널에서 Fire C++클래스 인스턴스를 선택하고, 노드 모양 버튼을 클릭해서 Fire C++ 클래스의 파생 블루프린트 클래스를 생성한다 (이름은 BP_Fire로 하자)
에디터가 열리면 빈 이벤트 그래프 영역에 우클릭해서 keyboard를 검색해서 키보드 이벤트 중에 F키에 대한 이벤트를 찾아 생성한다
그 다음에는 C++ 코드에서 블루프린트 호출이 가능하게 만들어둔 Off Fire 함수를 찾아서 키를 뗄 때 실행되도록 노드를 연결해준다
그리고 BP_Fire Class를 선택하고 블루프린트 에디터의 디테일 패널에서 Input 섹션의 Auto Receive Input을 Player 0으로 바꿔서 이 Fire 블루프린트 오브젝트가 바로 입력을 받을 수 있도록 만들어 준다
모든 작업이 끝나면 블루프린트 클래스를 컴파일한다
이제 BP_Fire을 레벨에 배치한 후 게임을 실행시킨 다음, F 키를 눌러보면 지정해 둔 연소 시간이 끝나기 전에 불 파티클이 꺼지는 모습을 볼 수 있다
VR게임 개발을 위한 언리얼엔진/C++ 공부한 내용 끄적이기...
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!