세션 관리 로직 통합

개발 일지|2024. 11. 17. 21:53

세션 관리하는 부분을 모두 GameInstance로 옮기고, 세션 관리 로직들을 테스트 해보는데

세션 생성은 되는데 레벨 이동이 일어나지 않는다.

 

어떻게 매번 에러가 새롭지?

'개발 일지' 카테고리의 다른 글

세션 생성 시도시 Fatal Error  (0) 2024.11.19
이번엔 월드스폰  (0) 2024.11.18
OnlineSubsystem  (0) 2024.11.16
7. 온라인세션? 쉽지않다  (0) 2024.11.12
6. UMG 디자인  (0) 2024.11.09

댓글()

OnlineSubsystem

개발 일지|2024. 11. 16. 22:16

계속 문제다. 오늘도 해결을 못했다.

 

우선 SearchResults에 검색 결과가 하나도 들어오지 않는다는것은 발견했다.

WAN 문제인가 해서 LAN으로 바꿔보기도 하고, 쿼리를 추가해보거나 했는데 바뀐건 없었다.

 

GameInstance로 일단 세션 관리 로직을 옮기고, GameMode 파일은 관련 로직을 다 비우자.

그리고 Session Travel쪽에서도 생성과 참가 모두 문제가 있는것 같다. 인지하고 있자.

 

게임이 시작되고 첫 세션 생성시 World 이동이 취소되고 다시 게임을 로드하는 문제도 이것과 관련이 있는것 같다.

뭔가.. 알아보면 알아볼수록 그냥 코드를 처음부터 다시 짜는게 더 빠를것 같기도 할것같은

 

문제가 너무 많아 어디서부터 손을 대야할지 감이 안오는 느낌이 살짝 든다.

OnlineSubsystem도 게임에서 하나의 객체만 써야하는데, 지금은 생성과 참가 모두에 새로 생성한다.

전에 하나로 통일했을 땐 세션을 생성해서 이동할때 처음 만들어진 세션으로만 이동하는 문제도 있었는데, 하나의 컴퓨터로 테스트 해서 그런건가?

 

어렵다 어려워.. 손에 잡힐듯 잡히지 않는 문제들이 해결되지 않고 점점 늘어난다.

'개발 일지' 카테고리의 다른 글

이번엔 월드스폰  (0) 2024.11.18
세션 관리 로직 통합  (0) 2024.11.17
7. 온라인세션? 쉽지않다  (0) 2024.11.12
6. UMG 디자인  (0) 2024.11.09
5. 멀티플레이 개발  (0) 2024.11.08

댓글()

user32.pdb not loaded

Error|2024. 11. 15. 21:32

무언가 안되서 디버깅을 하루종~~~~~일 하고있는데 하루종~~~~~~일 이 오류가 같이 뜨니까 괜히 화가난다.

그래서 뭐때문에 자꾸 떠서 신경을 긁어대는지 알아야겠다 싶어서 검색해봤다.

 

결론은 정상적인 실행과 아무 관련 없는 오류였다.

PDB 파일은 윈도우에서 디버깅을 하기 위해 필요한 정보 파일이며,

소스파일이 컴파일되는 중 생성된 심볼 파일이 디버깅 중에 필요한데 이게 로드되지 않아 발생하는것.

 

원인과 심각도를 알았으니, 해결을 해야겠지..

 

옵션->Debugging->Symbol로 들어가 마이크로소프트에서 필요한 심볼 파일을 다운받은 뒤 로드한다.

그러면 최초 로드될때 좀 기다려주면 깔끔하게 더이상 나를 괴롭히지 않는다.

'Error' 카테고리의 다른 글

UE5 컴파일시 Debug console만 뜨는 에러  (0) 2024.11.07
C++ LNK2005, LNK2001 에러  (2) 2024.10.07
ModRSsim Key 오류, MSVCR100.dll 오류  (0) 2023.08.28
응용프로그램의 side-by-side  (0) 2023.08.25

댓글()

헤드업디스플레이의 구현

Unreal 이론|2024. 11. 14. 18:19

[이득우의 언리얼 프로그래밍 Part2 수업의 정리]

 

[플레이어의 HP와 스탯을 표시하는 헤드업 디스플레이 UI의 구현]\

 

헤드업 디스플레이의 생성 과정

  • 헤드업 디스플레이 (HUD)는 플레이어 컨트롤러에 의해 제작되고 관리되는 UI객체
  • HUD의 구현은 위젯을 생성하고 이를 플레이어 뷰포트에 띄우는 과정으로 생성된다.
  • 이렇게 만들어진 위젯은 자신을 소유한 플레이어 컨트롤러에 접근할 수 있다.

HUD는 모니터 화면 전체를 다 쓰기 때문에 Canvas Panel 사용

  • 클래스 추가-> UserWidget 선택-> 클래스 생성 후 WBP_ABHUD의 클래스 세팅으로 가 해당 클래스를 Parent Class로 설정해 생성한 클래스를 상속받도록 설정
  • ConstructorHelper를 사용해 생성자에서 WBP_ABHUD를 가져오고, BeginPlay에서 CreateWidget->AddtoViewport를 사용해 화면에 띄워준다.
  • 블루프린트에서 쓰던거랑 똑같은 구조인걸 알 수 있다.
#include "Player/ABPlayerController.h"
#include "UI/ABHUDWidget.h"

AABPlayerController::AABPlayerController()
{
	static ConstructorHelpers::FClassFinder<UABHUDWidget> ABHUDWidgetRef(TEXT("/Game/ArenaBattle/UI/WBP_ABHUD.WBP_ABHUD_C"));
	if (ABHUDWidgetRef.Class)
	{
		ABHUDWidgetClass = ABHUDWidgetRef.Class;
	}
}

void AABPlayerController::BeginPlay()
{
	Super::BeginPlay();

	FInputModeGameOnly GameOnlyInputMode;
	SetInputMode(GameOnlyInputMode);

	ABHUDWidget = CreateWidget<UABHUDWidget>(this, ABHUDWidgetClass);
	if (ABHUDWidget) {
		ABHUDWidget->AddToViewport();
	}
}

 

초기화 프로세스의 정리

  • 컴포넌트, 액터, UI 위젯의 초기화 과정
  • 컴포넌트는 BeginPlay전에 컴포넌트가 가장 먼저 초기화되어 데이터가 확정되는것이 중요
  • Initalize Component로 스텟에 관한 데이터 먼저 초기화
  • 액터는 그 후 PostInitialize Components 함수로 안전하게 확정된 데이터를 쓴다
  • BeginPlay 이후 PlayerController는 CreateWidget으로 UI 위젯 초기화
  • UI위젯은 이때 NativeOnInitialized 함수 호출, 위젯이 생성되는것이고 눈에 보이진 않음
  • 눈에 보이려면 AddtoViewport 호출되야함. 이때 UI위젯에서 NativeConstruct로 위젯 확정지음



'Unreal 이론' 카테고리의 다른 글

게임의 완성  (0) 2024.11.23
게임 플로우 다듬기  (1) 2024.11.21
인공지능 - 행동트리 모델의 구현  (0) 2024.11.11
인공지능 - 행동트리 모델의 이해  (2) 2024.11.10
게임데이터 관리  (0) 2024.11.06

댓글()

자소서 작성

카테고리가 애매할 때|2024. 11. 13. 22:07

이때까지 회사에 지원할 때 자기소개서를 작성한 적이 없었다.

자소서라는 파일을 작성해서 제출하기보다는 지원하는 회사에서 작성하는 양식을 주고 그걸 작성하여 제출하기만 했었다.

 

오늘 처음으로 성장과정, 지원동기 및 입사후 포부, 내 성격의 장단점 등을 작성해봤는데 적어내기가 쉽지않았다. 특히 내 기술적 역량을 작성하는 부분이 정말 어려웠다.

 

내가 아직 봐줄만한 실력이 없어서 그런것이니.. 더 노력해야겠다.

댓글()

7. 온라인세션? 쉽지않다

개발 일지|2024. 11. 12. 21:39

결국 클릭한 UI를 강조 표시 해주는건 없앴다.

대신 UI를 클릭디자인만 바꿔서 유저가 뭘 클릭했는지 알 수 있게 해줬다.

 

그다음은 이제 대망의 세션 접속이다.

이 부분만 잘되면 그다음 진도는 잘 나갈것 같은데 쉽지않다..

 

클릭한 SessionList Widget Blueprint를 기억했다가 가지고 있는 UID를 Join Request 함수가 활성화될때 GameMode 클래스의 Join 함수로 넘겨버린다.

그걸 받고 SearchSetting을 구축해 Fname으로 세션 생성시 부여했던 UID와 비교해 일치하면 접속하는 간단한 구조이다.

 

근데 그 간단한게 작동하지 않는다.

테스트 환경이다보니 LAN으로 접속하는거라 WAN세팅으로 해놓아서 안되는건가 싶어서 LAN으로 설정을 바꿨다.

하지만 안된다.

세션 설정에 분명히 들어가있고, 이름도 일치하고, UID도 일치하고.. 뭐가 문제일까?

왜 찾지 못하는거지?

왜 해당 UID와 매칭되는 세션이 없다고 뜨는거지?

여러 방면으로 해결법을 찾고있긴 한데 되는게 없다.

빨리 고치자

'개발 일지' 카테고리의 다른 글

세션 관리 로직 통합  (0) 2024.11.17
OnlineSubsystem  (0) 2024.11.16
6. UMG 디자인  (0) 2024.11.09
5. 멀티플레이 개발  (0) 2024.11.08
4. 서버 구축을 위한 삽질  (0) 2024.09.02

댓글()

인공지능 - 행동트리 모델의 구현

Unreal 이론|2024. 11. 11. 15:52

[이득우의 언리얼 프로그래밍 Part2 수업의 정리]

 

패트롤 기능 구현

  • Blackboard에서 Vector Key인 PatrolPos 추가
  • 새롭게 스폰한 NPC가 새로운 섹션에서 랜덤으로 정찰할 포지션을 지정하기 위해 네비게이션 메쉬 볼륨 추가
  • Place Actor->Volume->NavMeshBoundsVolume 추가

NavMesh 구축 후 뷰포트에서 P키를 누르면 초록색으로 길찾기를 수행가능한 영역이 표시된다
동적으로 맵이 추가되기 때문에 NavMesh의 설정 중 Runtime Generation 옵션을 Dynamic으로 변경

  • Dynamic으로 설정을 변경하면 스폰 액터를 통해 생성된 섹션도 NavMesh를 사용가능
  • 행동 트리 설계를 위해 Build.cs에 NavigationSystem, AIModule, GameplayTasks 세개의 모듈 추가
// BTTask_FindPatrolPos.cpp

EBTNodeResult::Type UBTTask_FindPatrolPos::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	EBTNodeResult::Type Result = Super::ExecuteTask(OwnerComp, NodeMemory);

	APawn* ControllingPawn = OwnerComp.GetAIOwner()->GetPawn();
	if (nullptr == ControllingPawn) {
		return EBTNodeResult::Failed;
	}

	UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(ControllingPawn->GetWorld());
	if (nullptr == NavSystem) {
		return EBTNodeResult::Failed;
	}

	FVector Origin = OwnerComp.GetBlackboardComponent()->GetValueAsVector(BBKEY_HOMEPOS);
	FNavLocation NextPatrolPos;

	if (NavSystem->GetRandomPointInNavigableRadius(Origin, 500.0f, NextPatrolPos)) {
		OwnerComp.GetBlackboardComponent()->SetValueAsVector(BBKEY_PATROLPOS, NextPatrolPos.Location);
		return EBTNodeResult::Succeeded;
	}

	return EBTNodeResult::Failed;
}
  • 다음 정찰 위치를 찾는 태스크 추가

위와 같이 하드코딩을 통해 구현한 내용을 빌드 후 확인해보면 NPC가 제대로 움직인다.

이제 해야할건 인터페이스에 NPC가 가져야 할 내용을 구현한 후 뿌려주는것.

  • NPC 헤더를 직접 참조하지 않고 인터페이스를 통해 간접적으로 필요한 값을 얻어오도록 구조 수정
  • AIInterface 클래스에 필요한 값을 가져오는 가상함수를 추가 후 NonPlayer클래스에서 그 함수를 구현, PatrolPos 클래스에서 인터페이스를 캐스팅 해 그 함수를 가져와 간접적으로 값을 얻는 구조

  • BTService 클래스를 상속받은 유저감지 Detect 노드 추가
  • 서비스를 부착한 컴포짓 노드가 활성화 되면 TickNode가 지정한 Interval로 계속해서 호출된다.
  • 내용물을 구현하려면 TickNode에 구현해서 Interval마다 구현한 작업을 수행하도록 구성

구현한 Detect 서비스를 Sequence 노드에 부착

  • BlackBoard에 Target 변수 생성, 타입 Pawn으로 지정
  • 여기까지 한 후 실행을 눌러보면, NPC의 감지 반경과 감지 성공시 플레이어와의 거리가 뷰포트에 출력되는걸 확인 가능

  • 플레이어를 쫓아가서 공격하도록 Selector 추가
  • 언리얼 엔진이 기본으로 제공하는 Blackboard 데코레이터 부여, Key값을 Target으로 지정해 타겟이 설정되있을때만 셀렉터 컴포짓이 수행되도록 설정
  • 이후 Attack, AttackInRange 함수 구현.
  • 델리게이트로 NonPlayer에서 공격하는 로직이 호출되도록 구성
  • NPC도 플레이어처럼 PressCombo 함수를 호출해주고, 콤보가 끝나는 타이밍을 계산하기 위한 함수 CharacterBase에 추가
  • 과정이 꽤 길고 다양한 클래스들을 수정해 코드를 넣진 못했지만, CharacterBase에 공격이 끝난것을 알려주는 가상 함수를 선언하고 ComboActionEnd 함수 마지막에 호출되도록 추가 -> 가상함수는 NonPlayer 클래스에서 받아서 구현한 후 Attack 클래스에서 델리게이트를 묶어줘서 흐름이 굴러가게끔 설계
  • 빌드 후 실행해보면 캐릭터를 잘 쫓아와서 공격하지만, 캐릭터가 쓰러진 후에도 계속해서 공격 -> 셀렉터에 Detect 서비스 추가하면 캐릭터가 쓰러진 후 타겟이 없어지므로 해결

  • 캐릭터가 NPC 공격 중 회피를 했지만 NPC가 몸을 돌리지 않고 처음 공격 방향으로만 공격하는 현상 발생
  • BTTask 노드 추가 - TurnToTarget 클래스 생성해 이를 해결

  • Simple Parallel 컴포짓으로 Selector를 대체하고, Turn to Target 노드 추가
  • 이후 실행해보면 공격하며 동시에 타겟으로 회전하는 NPC를 확인할 수 있다.

'Unreal 이론' 카테고리의 다른 글

게임 플로우 다듬기  (1) 2024.11.21
헤드업디스플레이의 구현  (0) 2024.11.14
인공지능 - 행동트리 모델의 이해  (2) 2024.11.10
게임데이터 관리  (0) 2024.11.06
무한 맵의 제작  (0) 2024.10.31

댓글()

인공지능 - 행동트리 모델의 이해

Unreal 이론|2024. 11. 10. 15:32

[이득우의 언리얼 프로그래밍 Part2 수업의 정리]

 

행동 트리(Behavior Tree)의 역사

  • 2004년 개발사 번지의 헤일로2에서 인공지능을 설계하는데 사용됨
  • 2005년 GDC에서 발표 : "Handling Complexity in the Halo 2 AI"
  • 우선순위와 트리구조를 사용해 인공지능을 설계하는 기법
  • 단순한 행동에서 복잡한 행동으로 이어지도록 설계
  • 게임산업에서 개량해 널리 사용하고 있음

행동 트리 모델의 장점

  • FSM이 가지고 있던 문제를 해결하는 새로운 게임 인공지능 모델의 수립
  • 행동 트리 모델의 장점
    • 모듈화 잘 되어있어 확장 자유로움
    • 트리를 기반으로 계층화 잘 되어있어, 복잡한 인공지능 모델을 쉽게 설계할 수 있음
    • 다이어그램으로 인공지능 모델을 효과적으로 표현할 수 있음
    • 제공되는 여러 편리한 부가 기능을 활용해 다양한 상황에 대해 손쉽게 제어 가능

행동 트리 모델의 구성 요소

  • 트리에서 항상 왼쪽에 있는 노드에 우선 순위 부여
  • 시작 상태에서 설정할 필요 없이 왼쪽에서부터 깊이 우선 탐색(DFS)을 시작한다

Root에 의해 의사결정이 이루어진다

 

행동 트리 모델의 구성 요소

  • 행동을 중심으로 설계
  • 단, 부모 노드에서 다수의 행동을 컨트롤. 이를 컴포짓(Composite)이라 함
    • 셀렉터 (여러 행동 중 하나의 행동을 지정)
    • 시퀀스 (여러 행동을 모두 수행)
    • 패러렐 (여러 행동을 함께 수행)
  • ex) 밥먹기, 영화보기 두 행동이 있다면
    • 셀렉터: 밥과 영화 중 하나를 선택
    • 시퀀스: 밥을 먹은 후 영화를 봄
    • 패러렐: 밥을 먹으며 영화를 봄
  • 행동에 대한 다양한 결과
    • 성공 (Succeeded): 행동의 성공
    • 실패 (Failed): 행동의 실패
    • 중지 (Aborted): 외부 요인으로 인한 행동의 실패
    • 진행 중 (InProgress): 행동 결과를 홀딩
  • 컴포짓 노드마다 다른 행동 결과 처리
    • 셀렉터: 성공한 노드가 나오면 종료 (밥이 안나오면 대신 영화 시청)
    • 시퀀스: 실패한 노드가 나올때까지 진행 (밥을 안먹었다면 영화도 안봄)
  • 컴포짓 노드에 부착하는 다양한 추가 기능
    • 데코레이터(Decorator): 컴포짓 노드가 실행되는 조건 지정, 만족할때만 노드 실행
    • 서비스(Service): 컴포짓 노드가 활성화될 때 주기적으로 실행하는 부가 명령
    • 관찰자 중단(Abort): 데코레이터 조건에 부합되면 컴포짓 내 활동을 모두 중단

행동 트리 모델의 예시

  • 퇴근하고 집에 가는 행동 트리 모델의 설정
    • 지하철 역까지 이동 -> 지하철 탑승 -> 버스 환승 -> 문앞 도착
    • 시퀀스 컴포짓을 사용해 이들을 묶는다.

 

  • 트리가 가진 깊이를 활용해 단계별로 세부적인 행동 설계
  • 퇴근하고 집에가기 
    • 1단계: 지하철 역까지 이동한 후, 지하철 탑승, 버스환승, 문앞 도착
    • 2단계: 셀렉터 컴포짓을 사용해 지하철 역까지 걷거나 버스를 타거나 둘 중 하나 선택

 

컴포짓의 데코레이터 설정

  • 컴포짓에 조건을 걸어 선택의 폭 넓힐 수 있도록 확장
  • 우선 순위가 높은 컴포짓을 왼쪽에 배치, 데코레이터 설정

 

컴포짓에 관찰자 중단(Abort) 설정

  • 비상상황에 대한 처리. ex) 친구로부터 함께 놀자는 연락 왔다.
  • 트리 맨 왼쪽에 친구에게 간다는 컴포짓 추가
  • 집에 가는 모든 컴포짓에 친구와 약속이라는 Abort 추가
  • 친구에게 연락이 오면 집에 가던 모든 행동 중단 후 Root에서 다시 판단

행동 트리 모델의 구현 예시

  • 전형적인 RPG 게임 NPC에 대한 행동 트리 모델 예시
  • 쉬기(IDLE)와 정찰(PATROL)에 상태에 대한 행동 트리

  • 전형적인 RPG 게임 플레이어에 대한 행동 트리 모델 예시
  • 추가적으로 추격(CHASE)과 공격(ATTACK) 상태에 대한 행동 트리

 

그렇다면 실제 적용은 어떻게 하는가?

  • 월드에 배치된 캐릭터, SpawnActor 함수를 사용해 스폰시킨 캐릭터 둘 중 어느쪽에 AI를 적용할지 선택하는 Auto Possess AI 옵션. 둘다 적용하도록 선택
  • NPC 액터에 빙의할 AI 컨트롤러 클래스 선택하는 옵션 - 행동 트리 모델 적용한 클래스 새로 생성
// ABCharacterNonPlayer.cpp

#include "AI/ABAIController.h"

AABCharacterNonPlayer::AABCharacterNonPlayer()
{
	GetMesh()->SetHiddenInGame(true);

	AIControllerClass = AABAIController::StaticClass();
	AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;
}
  • NPC 생성자 코드에 AIControllerClass 할당

Behavior Tree, Blackboard 두가지 에셋을 추가

  • Blackboard: 인공지능 모델에서 의사결정을 하기 위한 기본 데이터 제공하는 데이터 저장소
// ABAIController.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "AIController.h"
#include "ABAIController.generated.h"

/**
 * 
 */
UCLASS()
class ARENABATTLE_API AABAIController : public AAIController
{
	GENERATED_BODY()

public:
	AABAIController();

	void RunAI();
	void StopAI();

protected:
	// 어떤 컨트롤러가 폰에 빙의해서 조종할때 발생되는 이벤트 함수
	virtual void OnPossess(APawn* InPawn) override;
	
private:
	UPROPERTY()
	TObjectPtr<class UBlackboardData> BBAsset;

	UPROPERTY()
	TObjectPtr<class UBehaviorTree> BTAsset;

};

// ABAIController.cpp
// Fill out your copyright notice in the Description page of Project Settings.


#include "AI/ABAIController.h"
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BlackboardData.h"
#include "BehaviorTree/BlackboardComponent.h"

AABAIController::AABAIController()
{
	static ConstructorHelpers::FObjectFinder<UBlackboardData> BBAssetRef(TEXT("/Script/AIModule.BlackboardData'/Game/ArenaBattle/AI/BB_ABCharacter.BB_ABCharacter'"));
	if (nullptr != BBAssetRef.Object)
	{
		BBAsset = BBAssetRef.Object;
	}

	static ConstructorHelpers::FObjectFinder<UBehaviorTree> BTAssetRef(TEXT("/Script/AIModule.BehaviorTree'/Game/ArenaBattle/AI/BT_ABCharacter.BT_ABCharacter'"));
	if (nullptr != BTAssetRef.Object)
	{
		BTAsset = BTAssetRef.Object;
	}
}

void AABAIController::RunAI()
{
	UBlackboardComponent* BlackboardPtr = Blackboard.Get();
	if (UseBlackboard(BBAsset, BlackboardPtr)) {
		bool RunResult = RunBehaviorTree(BTAsset);
		ensure(RunResult);
	}
}

void AABAIController::StopAI()
{
	UBehaviorTreeComponent* BTComponent = Cast<UBehaviorTreeComponent>(BrainComponent);
	if (BTComponent) {
		BTComponent->StopTree();
	}
}

void AABAIController::OnPossess(APawn* InPawn)
{
	Super::OnPossess(InPawn);

	RunAI();
}
  • 이후 ABAIController에서 Blackboard, BehaviorTree 에셋을 가져오고, 간단히 동작+정지 함수 구현

'Unreal 이론' 카테고리의 다른 글

헤드업디스플레이의 구현  (0) 2024.11.14
인공지능 - 행동트리 모델의 구현  (0) 2024.11.11
게임데이터 관리  (0) 2024.11.06
무한 맵의 제작  (0) 2024.10.31
아이템 시스템  (1) 2024.10.30

댓글()