Unreal Engine 5 – Full Course for Beginners
https://www.youtube.com/watch?v=6UlU_FsicK8
여태까지 기초였나보다.
Unreal의 Advanced가 얼마나 어려운지 한 번 경험해보자.
Level에 배치될 수 있는 모든 것은 Actor이다.
추가로, Actor만이 할 수 있는 것은 tick이다.
BP로 엑터를 만들고, Class Default로 들어간다.
Replication이 Actor에서만 볼 수 있는 기능이라고 한다.
이중에서 멀티에서 참고해야할 속성인 Replicates가 존재한다.
언리얼에는 기본적으로 Damage 이벤트가 존재한다.
3개나 존재하는데,
해당 Actor BP_A에는 다음과 같이 BP를 추가했다.
BP_A에 어떤 형태로든 Damage가 들어오게 되면, print하도록 한 것이다.
BP_Character라는 주인공 BP에서
왼쪽 클릭시 line trace했던 BP를 다시 연결해 보았다.
Damaged로 데미지를 받는 Actor는, line trace에서 hit된 객체이고,
Damage Causer 즉 데미지를 주는 Actor는, Character 본인,
그리고 Damage의 양은 랜덤의 Float값으로 주도록 했다.
문맥상 맞지만, Hit info없이는 Error가 뜨게 된다.
Recombine으로 HitInfo로 축약하여 접을 수 있고,
HitInfo를 그대로 인자로 먼저 주고,
break를 통해서 해당 HitInfo를 다시 세부적으로 나누게 된다.
Hit From Direction이라고 노란색 핀도 값을 넣어야하는데,
get Unit Direction 함수를 이용한다.
시작은 Trace가 시작되는 Trace Start로,
끝은, Trace End일 것 같지만, 해당 방식으로 하면, 땅을 뚫고
500000.0 cm 간 지점인데 의미 없는 값일 것이므로,
그냥 Location이라는 요소를 받는다.
해당 Location은, Line이 World Space와 닿은 곳을 의미하고,
땅을 뚫지 않는 지점을 가리킨다고 한다.
그렇게 Direction까지 설정하면 끝.
BP_A를 3개 배치하고, 쏘아보았다.
print string으로 10~40까지 랜덤 float Damage가 들어가는것을 볼 수 있다.
hit과 관련된 event는 여러개 있다.
현재 BP_A의 모델링에서 추가한 Sphere Hit과,
그냥 통용적으로 쓰이는 Event Hit이 존재한다.
이 중 Event Hit을 보긴하는데,
보통 모든 핀이 사용되는 것이 아니라 직접 인터페이스를 코딩하여 사용한다고 한다.
이 중 Event Hit을 본다.
BP_A에 충돌이 감지되면, 바로 hello를 출력한다.
해당 BP_A가 충돌하면 그냥 바로 출력된다.
Collision도 설정하지 않았는데 동작하는게 신기하다.
Actor BP에서 생성자는 특이하다.
해당 객체의 정보가 update되면, 해당 constructor를 실행한다.
예시로, 적용한 물체를 게임상에서 움직이면 움직이는 동안 생성자가 계속해서 실행된다.
run construction on drag
를 끄면 멈춘다.
float 변수를 만들고, Instance Editable과 Expose on Spawn을 체크한다.
expose on spawn을 하니, spawn 함수에 다음과 같이, Afloat핀이 보이게 된다.
정상적으로 지정된 spawn위치에 spawn이 된다.
afloat의 의미는 일단 없다.
이걸 CPP에서 해본다.
InteractionActor의 헤더를 먼저 Character CPP에 추가한다.
Character class에서 BeginPlay를 하면 다음과 같은 구문으로 Spawn을 시킨다.
여기서 spawn되는 것은, CPP_InteractionActor클래스의 객체이다.
왜인지 모르겠는데, 변수하나를 아래처럼 TSubclass로 만든다.
왜인지 설명
UPROPERTY를 사용하여, Actor To Spawn이란 변수를 BP에 보이고 싶은데,
해당 변수는 반드시 CPP_InteractionActor거나, 이를 상속받는 클래스여야만 한다고 방어적인 코딩을 하는 것.
그리고 해당 문장을 수정해준다.
Actor To Spwan이라는 변수에 객체가 할당이 되어있다면,
해당 객체를 World에 Spawn한다는 것이다.
그냥 if문 없이 처음 그대로의 코드를 쓰려면, Interaction Actor.cpp파일 생성자에 뷰포트에 띄우는 작업을 하면 될 듯하다.
그리곤 Interaction Actor에 uproperty로 int변수를 하나 추가했다. 왜?
tmp1과 2에 각각 넣어준다.
tmp2에 들어간 것은, deferred라는 것으로, 연기되다라는 의미인데,
그냥 Spawn Actor를 하면 바로 스폰이 되는 것을 막는 것이다.
반드시 FinishSpawning을 해주어야만 spawn이 된다.
그리고 매개변수로 transform을 넣어주어야만 하는데,
FTransform으로 기본 transform 정보를 생성하여 넣는다.
[Spawn_Actor_Deferred 참고]
추가로, auto로 받았으나, 형식은 ACPP_InteractionActor* 포인터 일 것이다.
그리고 해당 구문을 추가해 주었다.
잘못적었다. tmp2->nothing = 100; 이다.
그리고 InteractionActor의 BeginPlay에서는 nothing을 출력하도록 만들었다.
여태 상황을 정리해보자면,
Character에 Actor_To_Spawn이라는 변수를 하나 만들었고,
해당 변수에 InteractionActor클래스 객체가 들어있다면,
객체가 아닌듯하다. 그냥 설정되어있다면으로 수정
tmp1, tmp2 객체가 spawn되도록 하였다.
tmp1은 nothing이라는 InteractionActor 멤버변수를 100으로 세팅했다.
즉 ActorToSpawn에 InteractionActor객체가 들어가도록 BP를 만든다면, 동작하게 될 것이다.
전체화면으로 창을 켜야만 보이니 주의해야한다.
해당 Actor to Spawn이라는 부분이 보이게 되고, (edit_anywhere)
CPP_InteractionActor로 설정한다.
그렇게 실행하면, 문제가 생긴다.
좌표는 기본적으로 계속 출력하고 있는 무의미한 값이고, 예상한 것은,
tmp1이 생성될 때의 nothing값인 0,
tmp2가 생성될 때의 nothing값인 100 딱 2줄만 보여야하는데,
0이 많이 보인다.
보면 Interaction Actor는 단 2개만 생성되었다.
InteractionActor
생성시 단 1번 호출되어야하는 것인데, 왜 여러번 호출되었을까
deferred는 문제가 없으니, 그냥 spawn을 여러개 더 해보자.
맨 앞의 0 6개 호출되는 것 빼고 정상동작한다.
왜 먼저 불리는 걸까?
혹시 몰라 nothing값을 10으로 바꿔보았다.
nothing의 값이 확실하다.
왜?
위처럼 Interaction Actor를 상속받고 있는 것을 볼 수 있었다.
휴..
[6인의 범죄자들]
여태까지 몰랐었는데 소름돋게 딱 6개.