프로그래밍/Unreal 부트캠프

TIL 2025.05.15 기록

Rozentea 2025. 5. 15. 23:54

0. 개요


 

1. 프로젝트


이제 프랍 배치까지는 끝냈으니까 해당 프랍이 차지하는 Cell에 배치 불가 판정을 넣어서 GS_PlacerBase에서 배치가 가능한지 여부 검사를 할때, 배치하지 못하게 막아줄 것이다.

1. BuildObject() 함수에 영역 차지 기능 추가

원래는 GS_PlaceableObjectBase 클래스를 추가해 해당 클래스를 상속받아 몬스터와 프랍등 배치가 가능한 오브젝트들을 만들려했지만, Monster의 경우 GS_Character를 상속 받기 때문에 중간에 상속을 또 넣기가 애매하다.

 

때문에 해당 부분을 Component로 변경할까 했지만, Component로 넣기도 애매한게 기존 템플릿과 다르게 필요한 부분이 영역 차지 부분 뿐이고, 각각 Moster의 HP의 경우 Monster가 가지고 있기 때문에 또, 던전 에디터에서 배치했을때는 Monster가 움직이지 않고, 가만히 있기 때문에 굳이 동적으로 그때그때 차지하는 영역이 바뀌게 할 필요가 없다.
⇒ 물론 나중에 인게임에서 함정을 배치하거나 하는 기능을 추가할 땐 필요하겠지만..

 

때문에 우선 GS_PlacerBase에 해당 함수를 구현해 BuildObject()를 하면, 영역 차지를 부여해주도록 구현할 것이다.
⇒ 현재 영역 검사나 영역차지등이 TMap으로 관리하고 있기 때문에 괜찮을 것 같다.

 

BuildManager에 SetOccpupancyData() 추가

void AGS_BuildManager::SetOccupancyData(FIntPoint InCellPoint, bool InbOccipied)
{
	if (InbOccipied)
	{
		OccupancyData[InCellPoint] = 1;
	}
	else
	{
		if (OccupancyData.Find(InCellPoint))
		{
			if (OccupancyData[InCellPoint] < 2)
			{
				OccupancyData.Remove(InCellPoint);
			}
			else
			{
				OccupancyData[InCellPoint]--;
			}
		}
	}
}

c++의 map과 다르게 []해당 연산자는 값이 없을 경우 새로 Key와 Vaule를 추가를 해주는게 아니라 assert를 걸어버린다…

해당 로직에서 값을 확인하고, 없으면 Add 해주도록 수정해야할 것 같다.

오 찾아보니 저런 기능을 해주는 FindOrAdd()라는 함수가 존재한다.

이런 FindOrAdd() 함수는 non-const TMap에서만 사용이 가능하다.

void AGS_BuildManager::SetOccupancyData(FIntPoint InCellPoint, bool InbOccipied)
{
	if (InbOccipied)
	{
		OccupancyData.FindOrAdd(InCellPoint) = 1;
	}
	// ...

 

GS_PlacerBase의 BuildObject() 수정

void AGS_PlacerBase::BuildObject()
{
	bUpdatePlaceIndicators = true;

	DrawPlacementIndicators();
	if (bCanBuild)
	{
		bUpdatePlaceIndicators = true;

		FIntPoint CursorPoint = BuildManagerRef->GetCellUnderCursor();
		FVector2d CenterLocation = BuildManagerRef->GetCenterOfRectArea(CursorPoint, ObjectSize);
		FVector SpawnLocation = FVector(CenterLocation.X, CenterLocation.Y, BuildManagerRef->GetLocationUnderCursorCamera().Z);
		// 나중에 회전을 적용할때 FRotator를 넣어주면 될 것 같다.
		GetWorld()->SpawnActor<AActor>(ObjectData.PlaceableObjectClass, SpawnLocation, FRotator(0, 0, 0));

		// 영역 차지 로직
		TArray<FIntPoint> IntPointArray;
		CalCellsInRectArea(IntPointArray);

		for (int i = 0; i < IntPointArray.Num(); i++)
		{
			BuildManagerRef->SetOccupancyData(IntPointArray[i], true);
		}
	}
}

 

2. TempInGameLevel 제작

다들 실제 사용될 동일한 Level에서 테스트를 진행하는게 좋겠다는 판단이 들어서 임시 던전 맵을 먼저 제작하기로 했다.

해당 레벨은 추후에 던전 에디터를 이용해 다시 만들어 기본 템플릿으로 제공하는 레벨로 만들 생각이다.

 

1. 보스룸 제작

보스전에 입장하는 입구가 포탈 문 형식으로 변경되었는데, 그걸 플레이어가 직접 설치하게 하기에는.. 포탈문 모델링이 너무 아까워서 보스전에 진입하게되는 보스룸의 경우 완성을 시켜서 방단위로 배치를 하도록 결정했다.

아무래도 모든 방들을 이용하고, 방도 서로 연결해서 더욱 큰 방을 만드는 것까지 해두어야 할 것 같아서 최대한 다양하게 만들었다.

해당 레벨에서 테스트를 진행하고, 실제 게임이 진행되게 되면, 플레이 타임을 체크해 그리드 제한을 걸어서 방 배치를 최대로 할때, 적당한 플레이 타임이 되도록 정해야할 것 같다..

넥타르 수치도 그렇고.. ;ㅅ;

우선 위 맵으로 진행해보고 테스트해봐야겠다.