1. C++ 코드 작성
- NumberGameLibrary 클래스는 게임의 핵심 로직을 담당한다.
GenerateRandomNumber 함수는 1~9까지 중복 없는 3자리 숫자를 생성한다. 초기에는 TArray::Shuffle을 사용했으나, 컴파일 오류로 인해 Fisher-Yates 셔플 알고리즘을 수동 구현한다.
CalculateResult 함수는 서버 숫자와 사용자 입력을 비교해 스트라이크(S), 볼(B), 아웃(OUT)을 계산한다.
IsValidGuess 함수는 입력값이 유효한지(3자리, 중복 없음, 0 제외)를 검증한다. TSet을 활용해 중복 검사를 수행한다.
- NumberGameMode 클래스는 게임의 흐름을 관리한다.
ProcessGuess 함수는 플레이어의 입력을 처리하고, 턴 관리 및 승패를 판정한다.
ResetGame과 SwitchTurn 함수는 게임 리셋과 턴 전환을 담당한다.
BroadcastMessage 함수는 모든 플레이어에게 메시지를 전달한다.
NUMBERBASEBALL_API 매크로는 모듈 내보내기를 위해 추가한다. 단일 모듈에서는 생략 가능하지만, 표준 관행으로 포함한다.
2. 블루프린트 위젯 설정 (WBP_Chat)
- UI 구성:
ChatInput은 Editable Text Box로 사용자 입력을 받는다.
ChatOutput은 Text Block으로 게임 메시지를 표시한다.
SendButton은 Button으로 입력 전송을 트리거한다.
- 이벤트 그래프:
SendButton > OnClicked 이벤트는 입력을 처리한다.
Get ChatInput → Get Text로 입력값을 가져온다.
Get Game Mode → Cast To NumberGameMode로 게임 모드를 가져오고, Is Valid와 Branch로 유효성 검사한다.
Get Owning Player로 현재 플레이어를 식별하고, ProcessGuess를 호출한다.
- 마지막으로
Set Text로 ChatInput을 초기화한다.
ChatInput > OnTextCommitted는 Enter 키 입력을 처리한다. 로직은 OnClicked와 유사하다.
ChatOutput은 ChatMessage 변수를 바인딩해 실시간으로 메시지를 갱신한다.
3. 오류 해결
- C++ 오류:
Shuffle은 TArray의 멤버가 아니라는 오류가 발생했다. 수동 셔플 함수로 대체한다.
TSet의 Add 반환값(FSetElementId)에 ! 연산자를 사용할 수 없다는 오류가 발생했다. Contains로 중복 검사를 수정했다.
- 블루프린트 오류:
ProcessGuess 호출 시 "Target is None" 오류가 발생했다. World Settings에서 NumberGameMode 설정을 확인하고, Is Valid로 유효성 검사를 추가한다.
Get Text와 Set Text에서 Rich Text Block 타입 오류가 발생했다. Editable Text Box용 노드로 교체한다.
- 노드 연결 문제는 실행 핀(흰색)과 데이터 핀(파란색/빨간색)의 구분을 명확히 하여 해결해야 했다
4. 학습 포인트
- C++와 블루프린트의 연동은 성능과 편의성을 동시에 고려한다. 로직은 C++로, UI는 블루프린트로 분리한다.
- Unreal Engine의 노드 연결은 타입과 실행 흐름을 정확히 이해해야 한다.
Target 핀은 호출 대상의 타입과 일치해야 한다.
- 멀티플레이 환경에서는
Get Owning Player를 사용해 클라이언트별 컨트롤러를 식별한다.
- 오류 디버깅은 로그 추가와 단계적 테스트로 진행한다.