1) 형변환(Type Casting)
- 변수, 값의 타입을 변환
- 단순 타입 변수 데이터 : float, integer, string, boolean → 타입 변환(Convert) : ex. float → string
- 숫자를 문자로 바꾸는 것은 쉽지만 그 반대는 어려움 (A를 어떻게 바꾸는가?)
- 클래스 타입 변수, 데이터 : class, object, actor, character … → 캐스팅(casting) : 신호 보내기
- 특정 Actor가 필요한 Actor에게 Cast 신호를 보냄
- 신호를 받은 Actor는 변수, 함수를 쓸 수 있도록 해줌
- 신호를 보낸 Actor에서 특정 Actor의 변수, 함수를 사용 가능
2) Dialogue 제작
- Mixamo 캐릭터를 활용해 NPC 만들기
- 폴더 2개 만들기 : Dialogue → NPC
- NPC 안에 Blueprint Character 파일 추가
- 편집창에 들어가서 Mesh에 캐릭터 넣고 세부적인 요소 수정
- 애니메이션 모드를 Animation Use Asset으로 설정하고 애니메이션 동작 선택
- 서로의 대화 내용을 메인 캐릭터가 다 속하게 한다면 내용이 많아짐(프로그래밍 할 것이 많아짐)
- NPC들이 각각 대본을 갖고 있다면 찾을 필요가 없음 → 각 한 캐릭터당 하나만 갖고 있기 때문
- 사용하게 될 대본, 대화 시스템은 NPC가 갖고 있게 됨
- AI가 컨트롤해주는 AI 시스템이 필요함 : AI Controller 추가
- NP_NPC가 AI Controller를 사용해야 함 → NPC가 이 Blueprint를 포함하고 있음
- BP_NPC 편집창에서 Pawn을 검색해서 AI Controller Class 항목에 방금 만든 BP_NPC_AIController를 선택
- Character Blueprint와 AI Controller 두 개의 파일 연결 완료
- 대화창을 위한 UI를 만들기 위해 Dialogue 폴더 내 UI 폴더를 만듦
- HUD 방식의 UI로 진행할 것. Widget Blueprint 생성(WBP_HUD)
- Widget Blueprint 하나 더 생성 후 실제 대화가 나타나는 작은 대화창을 만듦(WBP_DialogueBox)
- 왜 따로 추가? (2가지 이유) → 틀이 되는 것과 대화창으로 사용하는 것
- 좌표 설정을 해줘야 하는 것이 따로 필요함
- 프로그래밍 상에서 단순해짐
- WBP_HUD는 캔버스 패널만 있으면 됨
- WBP_DialogueBox는 대화 창을 구성하는 용도의 패널을 넣으면 됨
- Horizontal Box와 Vertical Box 외로 많이 쓰는 Size Box 사용(픽셀로 정해 씀)
- Width Override : 300
- Height Override : 200
- Desired
- 대화하는 NPC의 질문이 주로 올라올 것 → NPC의 이름, 이야기 하는 내용 두 가지 섹션으로 준비
- Text를 Size Box 안에 넣기 위해 Canvas Panel을 추가 후 Border(컬러넣기. 이미지는 Image로)를 넣고 Text 넣기
- Size Box는 자신의 크기를 정할 수 있지만 그 안의 구성 요소는 디테일하게 사이즈, 배치가 어려움. 조정만 가능
- Border의 Anchor를 중앙 아래로 맞추기
- 양쪽을 채우기 위해 Offset Left, Right : 0
- Size Box : 300, 300
- Position Y : -200
- Size Y : 200
- Appearance 내→ Brush → Brush Color는 실제 Border나 Widget의 컬러를 바꾸는 부분
- 대화 내용의 폰트 사이즈는 16, 이름 사이즈는 20으로 구성
- WBP_HUD에 방금 만든 WBP_DialogueBox를 Palette 내 User Created에서 가져오기
- Size는 원래의 300, 300 지정
- Anchor는 다음의 위치로 지정해서 Alignment 지정(Position X/Y 0, Alignment 0.5/1.3)
- 화면에 띄우기 위해 Level Blueprint가 아닌 Blueprint Class에 UI를 띄울 수 있도록 함
- Widget은 웬만해서 캐릭터, NPC에 띄우지 말 것
- 전체적으로 관리하고, 처음부터 끝까지 있는 블루프린트 → 게임 컨트롤러를 제어하는 Game Mode (Game Mode Base)
- 게임 시작부터 종료까지 항상 같이 있는 것들
- Level Blueprint : 레벨 전체를 관리할 수 있는 프로그래밍 공간
- Game Mode : Blueprint Class, 게임 전체 관할
- Default Pawn : 캐릭터와 관련된 것만 사용
→ 여기서 가능한 건 Game Mode
- 기존의 게임 모드로 사용하던 파일인 BP_ThirdPersonGameMode 사용
- Event BeginPlay, Create Widget, Add to Viewport
- 평상시에는 UI가 안보이도록 설정 → 보였다 안보였다 컨트롤
- Detail 패널의 Visibility 항목에서 Hidden 선택 → 평상시에는 안보임
- WBP_Dialogue 박스를 변수로 만들어 컨트롤 할 수 있도록 Is Variable을 체크해 활성화
- NPC 와 대화를 위한 인터랙션 팝업을 만들기
- Widget Blueprint로 UI를 하나 더 생성 → WBP_TalkMessage
- Size Box 사이즈 설정. Size Box → Border → Text Block, 텍스트 중앙 정렬
- Width Override : 150
- Height Override : 50
- NPC 앞에 다가갔을 때 인터랙션 팝업이 뜰 수 있도록 BP_NPC의 충돌영역 만들기
- 편집창 내 Components에서 Box Collision 생성
- Shape Size 100, 100, 50
- WBP_HUD에 WBP_TalkMessage를 넣을 것(데려오는 것이 좀 더 수월) → 자잘한 UI 관할
- WBP_HUD에 WBP_TalkMessage를 화면에 띄우라고 하는 프로그래밍
- 언제 띄우라고 하는 것은 BP_NPC가 하는 것
- 실행 순서 NPC가 가지고 있는 Collision 영역에 메인 캐릭터가 들어옴
- Overlap Event 발생 → NPC가 WBP_TalkMessage를 띄워달라고 하면 이 UI를 HUD에 띄움
- BP_NPC의 EventGraph에서 HUD에 메세지 띄우는 것을 요청하도록 WBP_HUD에 있는 Talk Message 표시 함수 실행
- HUD에 TalkMassage를 넣는 프로그래밍 시작
- Canvas Panel 선택 후 디테일 패널 상단의 이름을 바꾸고(HUDCanvas) 변수처럼 사용하기 위해 IsVariable 체크
- Graph로 이동해서 Variable에 추가된 것 확인
- DisplayMessage라는 함수 생성
- 함수 하나로 보이거나 안보이게 하는 기능을 만듦
- Show Talk UI 함수에 Show Talk UI 인풋을 만들어 보이게 할 것인가 아닌가를 따져줌
- True / False(Branch)
- True일 때 보이고, False일 때 안보이게 함
- Viewport가 HUD의 Canvas에 보여지도록 해야함
- Add Child to Canvas
- Self는 HUD가 되는데 타겟은 HUDCanvas가 되어야 함
- Set Auto Size 노드 추가 연결 : 자동 크기로 설정(원래 콘텐츠 크기만큼)
- 위치는 메인 캐릭터의 위치를 기준으로 잡겠다고 설정
- Get Player Controller → 컨트롤러의 정보를 가져옴(키보드)
- 공간 좌표를 Viewport의 평면 좌표로 투영
- 대화와 관련된 건 NPC가 모두 갖고 있도록 함
- 현재 화면에 떠있는가 아닌가를 따짐 Talk UI I → WBP_TalkMessage를 넣음
- Get으로 TalkUI를 가져와 우클릭 → Convert to Validated Get(유요한 지를 따져보다 = 화면에 떠있는지 아닌지 따져보다)
- 화면에 띄우는 것과 동시에 변수를 담아주며 유요한 지 아닌지 체크
- 유요하지 않아야 화면에 띄워줌 → 떠있지 않으니 화면에 띄우겠다 Is Not Valid 와 Create Widget과 연결
- Is Valid : Talk UI 변수에 Widget이 있는지 확인
- Is Not Valid : Talk UI 변수에 Widget이 없는지 확인
- 화면을 띄워주는 건 Create Widget
- BP_NPC에서 실행하는 함수 만들기
- 제작한 Show TalkUI 노드를 불러오기. 불러와도 바로 실행은 불가. 타겟은 WBP_HUD. 변수를 하나 만듦
- WBP_HUD 타입의 변수를 선언 한다는 것은 그 블루프린트로 설정한 값들을 사용할 수 있다는 것
- HUD와 타겟의 연결성을 만들어 줄 필요가 있음
- 블루프린의 접점을 만들겠다(매개 역할) → 새 파일을 만듦
- Blueprint Interface를 생성
- Class Interface
- 비어있는 함수
- 기능을 주입
- 연결해주는 매개 역할
- Class Interface
- 이름을 InterfaceFunction으로 설정
- 이 껍데기 Interface 함수를 BP_NPC 파일이 쓰도록 함
- Class Setting을 누르고 디테일 패널에서 Implemented Interfaces 옆 Add를 눌러 아까의 Blueprint Interface 파일 추가
- HUD는 Widget이라서 가져올 수 없지만 ThirdPersonGame에 만든 것으로는 HUD 기능을 하고, Blueprint 이기 때문에 가져올 수 있음
- WBP_HUD가 어디에 있는지 알고 가져와야 함
- BP_ThirdPersonGameMode에 있는 걸 인지. 가져와야 하지만 서로 동일한 위치와 수준을 갖고 있기 때문에 그냥 가지고 올 수 없으나 서로 커뮤니케이션은 가능
- BP_NPC가 신호를 보내 BP_ThirdPersonGameMode에 신호를 보내서 그것에 대한 답을 함(내가 가지고 있는 데이터 써도 됨)
- BP_NPC는 BP_ThirdPersonGameMode가 가지고 있는 함수, 변수를 사용 가능
- HUD 변수에 WBP_HUD Widget을 대입
- BP_NPC로 이동해서 BP_ThirdPersonGameMode에 연락하기(Cast to~)
- 연락하고 싶은 Actor를 Object에 연결해서 Get Game Mode 가져오기. 그 안에서 BP_ThirdPersonGameMode를 찾아 연락
- Print String으로 테스트해서 잘 가져온 것을 확인
- GameMode의 HUD(BP_ThirdPersonGameMode)를 가져오는 것이 최종 목적 (Get HUD → WBP_HUD)
여기까지 정리
전제 조건 : NPC가 대화와 관련된 Object를 모두 가지고 있음(대사 및 충돌영역)
1. 플레이어 캐릭터가 NPC를 만나거나 멀어졌을 때
- NPC에 Collision, ThirdPersonGameMode를 Casting
- BeginOverlap Event 발생
2. NPC에서 Talk Message를 띄워주도록/제거하도록 요청 → HUD에 있는 함수 실행
- ShowTalkUI 함수 구현 : UI를 화면에 표시하거나 제거할 때, 관련 변수를 생성해서 표시할 때와 제거할 때 상태 표시 → 현재 UI가 표시되어 있는지, 제거되어 있는지 체크
3. HUD에 있는 함수 실행 → Talk Message 화면에 띄워줌
UI를 게임 시작부터 끝까지 관리할 수 있는 대상
- Level Bludprint : 전체를 관리하는 블루프린트 공간. Blueprint Class가 아니라서 캐스팅 불가
- Main Character : Blueprint Class 돌아다니는 것만 가능
- Game Mode : Blueprint Class
프로그램으로 접근 가능 → 대상이 필요(대상 : Blueprint Class, Widget Blueprint...)
- Blueprint Class에서 Casting을 통해 접근을 해야하기 때문에 접근 대상이 Blueprint Class가 되어야 함
- 메인 캐릭터도 가능하지만 웬만해서는 하지 말자
- WBP_HUD의 Graph에서 NPC가 Get Actor Location의 Target으로 들어감
- BP_NPC로 가서 Get Reference to Self로 자기 자신을 가져오는 노드로 연결
- 위치가 바뀜
- Split Struct Pin으로 Project World to Screen과 Set Position의 핀을 나누고 Add로 X, Y 각각 연결
- 멀어지면 TextMassage가 없어지도록 Show Talk UI 체크를 해제함
- Dialogue → Interface 안에 BPI_Interaction에서 함수의 이름을 바꿈(InterfaceFunction)
- 이것도 결국 NPC가 사용함. 대사 및 대본을 NPC가 갖고 있고 주도하도록 함 → AI Controller를 NPC에 연결하고, BPI_Interaction도 NPC에 연결할 것
- BP_NPC로 이동해서 Class Settings 버튼을 눌러서 Implemented Interfaces에 BPI Interface 선택하기
- 대화 주도, UI 띄우는 것 등 NPC가 주도함
- 그러나 T를 눌러 대화를 시작하는 것과 대답은 메인 캐릭터가 함
- 메인 캐릭터 Blueprint를 통해 T가 떴을 때, T를 눌러 대화를 시작하는 장치를 마련
- NPC,에 있는 Interface 함수를 실행하도록 메인캐릭터에서 T를 누르면 이벤트, 함수를 실행할 수 있게 만듦
- Variables에서 NPCActor 생성(Type : Actor)해서 Set으로 Event ActorBeginOverlap / Get으로도 가져와서 Cast to BP_NPC
- NPC가 충돌 영역에 다가갔을 때, 캐스팅에서 알아서 해주기 때문에 다가가면 대화가 실행될 것
- 대화를 할 수 있는 무언가를 실행되도록 함
- BP_NPC로 이동해서 연결해놓은 BPI 가져오기
- 인터페이스 이벤벤트가 발생되면 AI Controller에 캐스팅해서 대화 기능의 매개체 실행
- 이벤트를 발생시키겠다 → BP_NPC_AIController에서 Custom Event 생성 후 대화 시작과 끝에 대한 이름 수정 → Event BeginDialogue/EndDialogue(Behavior Tree를 실행시키기 위함)
- Behavior Tree : 행동과 관련된 것을 계층 구조로 표현한 것
- 어떤 Behavior Tree를 실행시킬 것인가? BTAsset에서 선택해야 하는데 아무것도 없음. NPC쪽에서 Behavior Tree에 접근할 수 있도록 만들 것
- 변수를 만들기 BTDialogue(Type : Behavior Tree)
- 변수의 데이터를 필요할 때 담는 것이 아닌 평소에 담아놓고 써야 함 → 시작은 기본으로 담아야 하기 때문에 Event BeginPlay를 할 때 담아야 함(시작 단계에서 가져오기)
- 변수 하나를 더 만들기 BTDialogueNPC(Type : Behavior Tree), 눈 켜기(레벨 편집 화면에서 변수의 값을 세팅할 수 있음)
- 프로그램 영역이 아니라 레벨의 편집 영역에서 설정할 수 있음
- Event Dialogue
- Behavior Tree 만들기 → 대화의 흐름 만들 것
- Behavior Tree와 연관된 에셋들을 만들기 위해 폴더를 만들고 AI → Behavior Tree 파일도 만듦(BT_Dialogue)
- 숫자 순으로 실행이 됨
Behavior Tree
전체 흐름 구성
- Selector : 자식 노드 중 하나가 성공하면 나머지를 무시하고 성공으로 평가
- Sequence : 모든 자식 노드가 순차적으로 성공해야 전체가 성공으로 평가
- Simple Parallel : 자식 노드를 동시해 실행하며, 특정 노드가 성공하면 성공으로 평가
기능 실행
- Task : AI 캐릭터가 수행해야 하는 특정 행동을 정의함. Ex) 이동, 공격, 대기 등
데코레이터
- Task에 추가해줄 수 있는 기능. 특정 노드에 추가적인 조건이나 제한을 설정하는 역할
- 대화와 관련된 Tree를 생성
- Sequence와 Selector로 흐름을 만들기
- 대화창을 보이게 하는 것부터 대화의 시작
- New Task를 눌러 저장해서 에셋을 만들기. 여기서 DialogueBox가 보여지도록 노드 프로그래밍
- 대화창에서 이름도 보일 수 있도록 이름을 넣어줄 변수를 BP_NPC에서 만들기 → Name(Type : Text), 눈 켜기
- 다시 BTT_ShowDialogueBox에 가서 HUD, NPC 캐스팅을 해야함
- AI로 끝나는 Event를 써야함 → 실행을 해야하므로 Event Receive Execute AI
- 실행핀에 Cast to BP를 검색 후 실행(Cas to BP_ThirdPersonGameMode)
- Dialogue Box를 쓰려고 GameMode HUD를 가져옴 → WBP_DialogueBox 연결
- WBP_HUD에서 WBP_DialogueBox를 DialogueBox로 이름을 바꿈
- Visibility → visible로 보이도록 바꿈
- BT_Dialogue에서 BTT_ShowDialogueBox 추가
- Behavior에서 일어나는 일들을 저장하는 BlackBoard 생성
- Root → Behavior Tree → None 클릭 → Blackborad를 클릭해 새 파일 만들기
- 데이터를 정리하는 방법 중 하나가 (Key(제목 / 이름) - Value) 데이터를 구분하기 좋게 만들어 놓음
- Blackborad에서 Key는 중요한 개념
- Type : Object / Entry Name : DialogueBox
- BBDialogueKey 변수를 만들기(Type : Blackboard Key), 눈 뜨기
- 눈을 뜨게 되면 BT_Dialogue파일에서 BTT_ShowDialogueBox 노드에 BTTDialogueKey를 DialogueBox로 바꾸기
- 여기까지 T를 누르면 Dialogue Box가 생성되고, 대화창이 뜨는 것이 확인됨
- 내용을 넣어보고, 이름도 입력해서 뜨는지 확인
- BTT_ShowDialogueBox에서 이름을 가지고 있는 NPC 캐스팅
- AI에 의해 컨르롤 받는 NPC
- 해당 위치에 이름을 쓸 수 있게 해야 함 = 해당 부분을 변수처럼 써야 함
- WBP_DialogueBox 파일의 Graph에서 이름이 들어가는 부분, 대화가 들어가는 부분에 대해 각각 변수를 만들어주고 눈을 켜주기
- NPC Name(Type : Text) / Dialogue Text(Type : text)
- Designer에서 Content의 Bind에서 NPC Name 클릭
- NPC Name에 실제 이름 넣어주기
- WBP_DialogueBox는 HUD 포함, BTT_ShowDialogueBox는 이미 캐스팅해서 HUD를 가져옴
- Task 추가 : 대화를 대화 창에 넣기
- 중간에 둘을 이어주는 매개체(Blackboard)가 필요함 (저장)
- Set Blackboard Value as Object 노드 생성. Value에 넣어 저장하는 값 생성
- 대화가 시작되면 마우스로 선택지를 선택할 수 있게하고, 마우스 커서가 보이도록 하기
- Input을 못하게 막음(키보드, 마우스...)
- 대화할 때 마우스 커서는 보이고 움직임은 멈춤
- 성공적으로 실행이 끝났다는 Finish Execute 노드 추가, Success 체크
- Behavior Tree가 다음 태스크로 넘어가야겠다고 판단
- 새로운 Task 만들기 → BTTask_BlueprintBase_New. 기존에 만든 태스크 이름을 선택하면 새로운 태스크가 만들어짐
- 대화창 캐스팅. Blackboard에 저장해 놓은 것을 가져다 쓸 수 있음
- 대화 내용을 담을 변수도 생성 → DialogueBoxText(Type : Text)
- Designer에서 WBP_DialogueBox의 Content의 Bind를 이걸로 지정
- BT_Dialogue 파일(외부)에서 쓸 수 있게 새로운 태스크 변수들의 눈을 켜줌
- Behavior Tree에서 새로운 태스크 꺼내기. 키가 똑같아야 저장된 위치로 찾아갈 수 있음
- Task Dialogue Text에 내용 적으면
'4. 언리얼 엔진(Unreal Engine) 공부 > Unreal Engine [이론]' 카테고리의 다른 글
24. [UE5] NPC 만들기(정적/동적/Socket) (2) | 2024.11.03 |
---|---|
23. [UE5] UI Interaction(Widget) (0) | 2024.10.30 |
22. [UE5] 다른 액터와 캐릭터가 상호작용 하기(Overlap, CutScene, LevelBlueprint) (1) | 2024.10.23 |
21. [UE5] 블루프린트를 위한 프로그래밍 기초 (1) | 2024.10.18 |
20. [UE5] 블루프린트를 활용한 캐릭터 움직임 제어 (0) | 2024.10.14 |