[ Unreal Engine 5 / #25 Tile Game 기능추가 ]

SeungWoo·2024년 10월 22일
0

[ Ureal Engine 5 / 수업 ]

목록 보기
26/31
post-thumbnail
  • 현재 TileGame 의 두 Tile을 선택하고 교환 할 수 있다. 하지만 Tile 게임에서 상하좌우 상태에서만 교환이 되기 때문에 그 부분을 수정 하겠다

  • 인접한 타일끼리만 교환 가능

    • 타일의 그리드 위치를 추적하여 두 타일이 인접한지 확인.
    • 가로 또는 세로로 인접한 경우만 두 번째 타일을 선택할 수 있도록 제한.
    • 대각선으로 인접한 타일은 선택 불가능하게 구현

  • 아직은 정상 작동 하지않는다

  • 비동기 작업의 순서 문제

    • 비동기 작업은 병렬로 실행되기 때문에, AsyncTask 내부에서의 작업이 보장된 순서로 실행되지 않음. 즉, 타일들이 정확한 순서로 생성되지 않음
  • 비동기 작업을 유지하면서 해결하는 방안

    • 만약 비동기 작업을 유지하고 싶다면, 동기화 메커니즘을 추가하여 모든 타일이 완전히 생성된 후에만 다른 작업이 실행되도록 해야함
    • 타일 생성 완료 여부를 체크 :
      모든 비동기 타일 생성 작업이 완료될 때까지 기다린 후, 타일 스왑 등의 작업이 실행
    • 타일 생성 완료 후 이벤트 트리거 :
      모든 타일이 생성되었을 때, 이벤트를 트리거하여 TileSwap이나 매칭 로직 등의 후속 작업을 처리

비동기작업Ver.

ATileGrid::ATileGrid()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	
	GridWidth = 8;
	GridHeigh = 8;
	TileSpacing = 100;
	TileArray.SetNum(GridWidth * GridHeigh); 
	// 1차원 배열로 메모리 할당 8*8 형태
}

void ATileGrid::InitializeGrid()
{
	// 가능한 TileType 리스트
	TArray<FName> TileTypes =
	{
		FName("Cone"),
		FName("Cube"),
		FName("Cylinder"),
		FName("Sphere"),
		FName("Capsule"),
		FName("Pyramid")
	};

	for (int32 x = 0; x < GridWidth; ++x)
	{
		for (int32 y = 0; y < GridHeigh; ++y)
		{

			// 비동기적으로 타일을 생성
			AsyncTask(ENamedThreads::GameThread, [this, x, y, TileTypes]()
				{
					// 타일 타입을 핸덤하게 결정 ( 비동기 작업 )
					FName RandomTileType = TileTypes[FMath::RandRange(0, TileTypes.Num() - 1)];
					
					// 게임 스레드에서 타일 생성과 외형 설정을 처리
					AsyncTask(ENamedThreads::GameThread, [this, x, y, RandomTileType]()
						{
							if (!TileClass)
							{
								UE_LOG(LogTemp, Warning, TEXT("TileClass is not Valid "));
								return;
							}
							
							FActorSpawnParameters SpawnParams;
							ATile* NewTile = GetWorld()->SpawnActor<ATile>(TileClass, SpawnParams);

							if (NewTile)
							{
								// 타일 그리드 참조
								NewTile->TileGrid = this;
								// 타일의 그리상의 위치
								NewTile->TilePosition = FVector2D(x, y);

								// 생성된 타일의 타일 설정
								NewTile->TileType = RandomTileType;

								// 타일 종류에 따라서 외형 업데이트
								NewTile->UpdateTileAppearance();

								// 타일을 TIleGrid의 자식으로 부착
								NewTile->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);

								// 타일을 그리드에 배치
								FVector RelativeLocation = FVector(x * TileSpacing, y * TileSpacing, 0.0f);
								NewTile->SetActorRelativeLocation(RelativeLocation);

								// 그리드에 타일 저장
								SetTile(x, y, NewTile);

								UE_LOG(LogTemp, Warning, TEXT("Tile Create at [ %d, %d ] with type %s "), x, y, *RandomTileType.ToString());

							}
							else
							{
								UE_LOG(LogTemp, Warning, TEXT("Failed to Spawn Tile at [ %d, %d ]"), x, y);
							}

						});
				});
		}
	}
	// 가능한 TileType 리스트
}
profile
This is my study archive

0개의 댓글