Unreal Engine 5 – Full Course for Beginners
https://www.youtube.com/watch?v=6UlU_FsicK8
Blueprint는 전체 강의의 1/4를 차지하고, 아직 반도 되지 않았다.
blueprint로 이제 뭔가를 해보자, object-블루프린트
를 생성한다.
벡터라는 클래스를 다음과 같이 만들고 객체를 실제로 생성해본다.
벡터는 이미 언리얼에 구현이 되어있다. 예시로 만들어보는 것
멤버변수의 필드 설정은 프라이빗을 체크하는것으로 설정한다.
그리고 변수로 승격이란것을 한다.
즉 아래 구조의 의미는,
Vector2 v2 = new Vector2 와 같은 의미인 것이다.
해당 클래스 객체를 생성하고, 변수에 대입한 것이기 때문.
Vector2라는 사용자 클래스에, 사용자 함수도 넣어주었다.
Set함수이다.
각 멤버변수를 출력하는 print함수도 만들었다.
하지만 경고가 뜨게 된다.
그 이유는, 어떤 객체의 변수값을 출력하는 것인지 대상이 정해지지 않았기 때문이고, 아래처럼 self 오브젝트를 가져옴으로써 수정한다.
위의 식을 간단히 할 수 있는 기능 append
가 존재한다.
print할 요소를 append로 받는다.
핀추가를 하여 Cout의 <<
와 비슷한 느낌으로 사용한다.
최종적으로 아래처럼 연결하여 사용한다.
blueprint는 구조체를 가질 수 없다.
하지만, 클래스와 구조체가 C++에선 같은 것이라는 관점하에, 클래스처럼 만들면 된다.
오브젝트-블루프린트
사용
액터는 가장 많이 쓰이고 파생되는 blueprint이다.
그리고 레벨에 직접 배치할 수 있다.
액터를 열면, 탭도 3개에 복잡한 구조를 가진 것을 볼 수 있다.
먼저 이벤트 그래프 부분부터 본다.
그 중 첫번째는 BeginPlay 이벤트이고,
해당 블루프린트액터가 spawn으로 생성되거나,
시작하기 전 레벨에 배치한 경우, 호출이 된다.
해당 BP로 여러개를 배치했다면, 해당 동작이 각각 실행된다.
Event tick은 유니티의 Update문과 비슷하다고 봤었고,
프레임마다 반복한다. 해당 주기는 클래스디폴트-틱 간격(초)에서 설정할 수 있다.
All settings that will be there will be usually exposed as functions to be adfusted at runtime,
otherwise again you have your class defaults
where you can actually set them.
모든 설정은, 런타임때 조절되지만,
기본적인 값이 존재한다.? 중요한 것 같은데 무슨말인지 모르겠다.
Actor BP의 뷰포트로 넘어간다.
스켈레탈 매쉬는 캐릭터의 뼈대와 애니메이션 등을 의미하고
pickups와 같은 일반적인 물체는 정적 메쉬가 될 것이라고 한다.
그래서 기존 default를 삭제하고 스태틱 매쉬를 넣는다.
루트의 교체가 맞는 표현
피직스 시뮬레이트를 키고 스태틱매시를 추가했고, 뷰포트에서도 적용된다.
내리막길을 따라 굴러가게 된다.
물리의 적용과 충돌까지 감지하게 된다고 한다.
충돌을 실제로 감지하기 위해서는, 바운드가 필요하다고 한다.
유니티로 치자면 현재 Rigidbody3D를 객체에 적용은 했지만,
Collision은 적용하지 않은 개념인 듯 하다.
그래서 아래와 같이 collision을 지정해 준다.
그러면 충돌시 해당 이벤트가 호출이 된다.
3개 중에 하나 설명하지 않은 이벤트가 충돌collision의 겹침
을 판별하는 이벤트였다
그래서 아래처럼 함수를 적용하고 실행하니, 충돌을 정상적으로 감지하는 모습이다.
각 공들끼리의 충돌도 감지하지만, 1인칭인 카메라와의 충돌도 감지한다.
cast to pawn 기능이다.
우선, event의 other Actor는, 현재 해당 BP에 겹치는 actor를 의미하고,
cast to pawn이라는 것은, pawn으로 형변환 한다는 것이고,
업캐스팅으로 형변환을 의미하는 듯 하다.
그래서 해당 물체를 업캐스팅 시, pawn이 존재한다면,
즉, [pawn]을 상속받은 객체라면 정상적으로 실행되는 것이고,
그것이 아닌, cast Failed라면, 해당 과정으로 실행되는 것이된다.
즉 아래의 BP를 해석한다면, 해당 BP가 적용된 객체가 부딪힌 물체를
pawn으로 캐스팅 할 수 있는 pawn객체라면,
다음 함수를 실행하는 함수인 것이다.
자세한 내용 해당 사이트 참고
pawn을 상속받는 객체로 대표적인 예는 1인칭으로 제어하고 있는 카메라이다.
플레이어나 AI도 pawn을 상속받는다고 한다
그래서 부딪히면 그대로 DIDIDIDI를 호출하게 했는데, 동작한다.
그 외의 pawn을 상속하지 않는 객체의 경우 HA를 출력하게 했다.
시작할 때, 부딪히게 설정했고, 정상적으로 동작한다.
서로 겹치기에 서로 출력하는 것이고 많은 HA가 출력되게 된다.
이해한 것만 설명해보자면, 가장 기초가 되는 것은 object이고,
해당 기능을 상속받은건 actor이고 실제로 구현하여 레벨에 배치할 수 있게 된다.
왼쪽으로 파생되면 컨트롤러이고, 플레이어 컨트롤러는 컨트롤러를 상속받았다.
여기서 컨트롤러들은 액터의 파생이지만, 레벨에 배치할 수 없다.
오른쪽으로 파생되면 pawn이고,
pawn은 레벨에 배치가 가능하고, player controller는 항상 pawn을 소유한다.
pawn을 상속받는 것은 character이고, pawn의 특수한 경우이다.
대부분의 기능이 character에 구현되어있고, 실제로 가장 많이 사용할 것이라고 한다.
character는 보통 움직이는 동물을 위주로 사용한다.
player controller는 character도 소유할 수 있다.
위의 내용이 정확히 맞는지 모르겠어서 추가적인 영상을 찾아보았다.
설명을 보면 계층구조가 보인다.
액터를 상속받는 폰을 상속받는 캐릭터인 것이다.
액터는 오브젝트를 화면에 배치하고 모양이 나타나게하고 그런 일반적인 기능이 있고,
이를 기반으로 사용자나 AI가 움직일 수 있는 기능까지 추가한 것이 폰이고,
이를 기반으로 어떤 동작 즉, 애니메이션 기능까지 구현한 것이 캐릭터라고 한다.
Actor는 건물, 도로
Pawn은 체스말, 자동차
Character는 사람, 동물
그냥 모든 물체를 character로 만들면 되지만,
쓸데없이 메모리를 차지하지 않게 하기 위해서, 최적화를 위해서 나눠놓은 것이다.
정말 명쾌하게 알았다.
뭔가 많이 존재한다.
먼저 메시부터 사람 형태로 바꿔주었다.
화살표가 존재하는데, 실제 정면방향이고,
그러므로 캐릭터를 돌렸다. 그리고 collision에 맞게 z축을 내렸다.
mesh에서 애니메이션도 바꿔보았다.
왜인지는 모르겠지만 world 세팅에서 game mode로 모드를 바꾼다.
그리고 game mode base로 BP를 생성한다.
game mode나 mode base나 중요하지 않다고 함
그리고는 생성한 BP_GameMode로 게임모드를 또 바꾼다.
게임모드를 사용자 모드로 수정하면 원래 바꾸지 못했던 설정들이 풀리는데,
아래에 디폴트 폰 클래스를 캐릭터로 바꾼다.
실제로 플레이어가 바뀐다.
하지만 움직일 수는 없다.
카메라를 배치한다. 시야가 바뀌는 것을 볼 수 있다.
이동은 직접 구현해야 한다고 한다.
w key로 키보드의 w방향을 인식할 수 있다.
최종 코드,
Add MovementInput은 적용된 객체가
World Direction 방향으로,
Scale Value 값만큼 움직이는 함수인데, 어찌저찌 가져와서 붙이니
작동은 하는 블루프린트가 되었다.
하지만 위 방법보다 더 좋은 방법이 존재한다고 한다.
아래처럼 축에 대한 정의를 세팅해주면, 블루프린트와 C++에서도 사용가능하다고 한다.
실제로 이벤트가 생겼다.
그리고 아래처럼 3개의 노드만으로 동작한다.
사실상 입력이 w면 1.0의 값을, s면 -1.0의 값을 뱉도록 함수만 만들었는데,
방향만 설정해두고 이동하도록 설정하니,
해당 정해진 키가 눌릴 때마다 event가 실행이 되고,
눌린 키에 따른 값이 리턴되므로, 방향만 설정해주니 깔끔하게 이동을 구현할 수 있게 된다.
그 외의 것들을 생성중에 있어서 마우스로 위아래 카메라제어가 되지 않았는데,
카메라 설정에서 제어를 켜줘야만 한다.
다음과 같이 모든 이벤트를 구현해 보았다.
Player Controller를 만들 것이다.
캐릭터가 파괴되더라도 다시 생기게 하거나 제어할 수 있도록 한다.
아래의 camera rotate되는 값을 조절하는 것을 controller에서 해보려고 한다.
컨트롤러-BP를 생성하고, 함수로 0.5의 값을 받도록 한다.
그 전에 컨트롤러를 인식시킨다.
BP를 앞에 붙이는 이유가 있었다.
그리고 player 캐릭터에서 해당 컨트롤러 객체를 생성하는데,
방식이 독특하다.
get player controller로, 모든 플레이어 컨트롤러 클래스를 가져오고, (해당 프로젝트에선 하나만 만들었기 때문에 문제가 없다)
해당 controller가 BP_PlayerController로 cast할 수 있다면,
promote(set)
로 변수화 시킨다. 여기서는 PCref
왜 그냥 바로 PlayerController 하나밖에 없는걸 변수화시키지 못하는가 하냐면, 리턴이 뭐든간에 PlayerController로 설정이 되기 때문이다.
그래서 해당 객체의 sensitivity 함수를 통해 민감도 값을 가져와서 적용하는 식이다.
플레이어 컨트롤러는 무조건 캐릭터가 생성되기 전에 생성된다.