
LLM
GPT한테 일을 시키는 것은 좋으나 생각보다 오류가 많기 때문에 최대한 알고리즘 혹은 로직에 대한 이해를 한 상태에서 불필요한 것들을 제거하는 방식으로 가는 것이 효율이 좋다.
사용자가 무조건적으로 LLM을 신뢰하는 것은 원하는 결과를 만들 수 없다.LLM으로 생성한 코드
하고싶은 것은 결국 LLM으로 로직을 작성하고 블루프린트에서 조정을 하고 싶은 것이다
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MazeBlueprintLibrary.generated.h"
USTRUCT(BlueprintType)
struct FCell
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool IsVisited;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool TopWall;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool BottomWall;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool LeftWall;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool RightWall;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 PlayerStartNum;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool IsGoal;
FCell()
{
IsVisited = false;
TopWall = true;
BottomWall = true;
LeftWall = true;
RightWall = true;
PlayerStartNum = -1;
IsGoal = false;
}
};
UCLASS()
class YOURPROJECT_API UMazeBlueprintLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Maze")
static void GenerateMaze(int32 Width, int32 Height, UPARAM(ref) TArray<FCell>& OutCells);
private:
static void InitializeMaze(int32 Width, int32 Height, TArray<FCell>& Cells);
static void GenerateMazeRecursive(int32 X, int32 Y, int32 Width, int32 Height, TArray<FCell>& Cells);
static int32 GetIndex(int32 X, int32 Y, int32 Width);
static bool IsValidCell(int32 X, int32 Y, int32 Width, int32 Height);
};
#include "MazeBlueprintLibrary.h"
void UMazeBlueprintLibrary::GenerateMaze(int32 Width, int32 Height, TArray<FCell>& OutCells)
{
InitializeMaze(Width, Height, OutCells);
// (0, 0)에서 시작 (랜덤 시작점을 원한다면 수정 가능)
GenerateMazeRecursive(0, 0, Width, Height, OutCells);
// 시작점과 목표 지점 설정 (예시)
OutCells[0].PlayerStartNum = 0; // (0, 0)을 시작점으로
OutCells[Width * Height - 1].IsGoal = true; // 마지막 셀을 목표로
}
void UMazeBlueprintLibrary::InitializeMaze(int32 Width, int32 Height, TArray<FCell>& Cells)
{
Cells.Empty();
Cells.SetNum(Width * Height); // Width x Height 크기로 셀 배열 설정
// FCell 생성자에서 기본값이 이미 설정됨
}
void UMazeBlueprintLibrary::GenerateMazeRecursive(int32 X, int32 Y, int32 Width, int32 Height, TArray<FCell>& Cells)
{
int32 CurrentIndex = GetIndex(X, Y, Width);
if (!IsValidCell(X, Y, Width, Height) || Cells[CurrentIndex].IsVisited)
{
return;
}
Cells[CurrentIndex].IsVisited = true;
// 방향 배열 (상, 하, 좌, 우)
TArray<FIntPoint> Directions = {
FIntPoint(0, -1), // 상
FIntPoint(0, 1), // 하
FIntPoint(-1, 0), // 좌
FIntPoint(1, 0) // 우
};
// 방향을 랜덤으로 섞기
Directions.Sort([](const FIntPoint& A, const FIntPoint& B) {
return FMath::RandBool(); // 무작위 정렬
});
// 각 방향 탐색
for (const FIntPoint& Dir : Directions)
{
int32 NewX = X + Dir.X;
int32 NewY = Y + Dir.Y;
int32 NewIndex = GetIndex(NewX, NewY, Width);
if (IsValidCell(NewX, NewY, Width, Height) && !Cells[NewIndex].IsVisited)
{
// 현재 셀과 다음 셀 사이 벽 제거
if (Dir.X == 1) // 오른쪽
{
Cells[CurrentIndex].RightWall = false;
Cells[NewIndex].LeftWall = false;
}
else if (Dir.X == -1) // 왼쪽
{
Cells[CurrentIndex].LeftWall = false;
Cells[NewIndex].RightWall = false;
}
else if (Dir.Y == 1) // 아래쪽
{
Cells[CurrentIndex].BottomWall = false;
Cells[NewIndex].TopWall = false;
}
else if (Dir.Y == -1) // 위쪽
{
Cells[CurrentIndex].TopWall = false;
Cells[NewIndex].BottomWall = false;
}
// 다음 셀로 재귀 호출
GenerateMazeRecursive(NewX, NewY, Width, Height, Cells);
}
}
}
int32 UMazeBlueprintLibrary::GetIndex(int32 X, int32 Y, int32 Width)
{
return Y * Width + X; // 2D 좌표를 1D 인덱스로 변환
}
bool UMazeBlueprintLibrary::IsValidCell(int32 X, int32 Y, int32 Width, int32 Height)
{
return X >= 0 && X < Width && Y >= 0 && Y < Height;
}
블루프린트 라이브러리로 만들었기 때문에 복붙딸각해주면 편하게 미로를 만들 수 있다 !
리슨서버
멀티플레이 게임을 만들때는 딜레이를 무조건 주어야 한다.
리플리케이션이 일어나는데 걸리는 시간이 존재하기 때문이다.
최소 3초 이상은 주어야 한다.
데디케이트
실무에서의 데디케이트 언리얼에서의 리슨 혹은 데디케이트서버는 콘솔기반 게임에 적합하다.
한국의 서버는 Persistent서버다 닫히면 안되는 서버기 때문에 GameInstance의 상태를 계속 업데이트 하는 것이다.
UnrealEngineDedicatedServerManager검색해보자.
서버가 열리고 닫는 것을 전제로 설계가 되어있기 때문에 24시간 돌아가는 서버를 고려하면 적합하지않다.
세션에 대한 자료는 꽤 있는데 의외로 리슨서버나 데디케이트 서버에 대한 자료를 찾기가 힘들다
내일은 ChatBaseball과 미로위에서 케릭터 2개이상 서는것을 확인해보자.