diff --git a/DungeonGenerator.uplugin b/DungeonGenerator.uplugin index eab58b9..ab7f8f5 100644 --- a/DungeonGenerator.uplugin +++ b/DungeonGenerator.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, - "Version": 6, - "VersionName": "1.4.1", + "Version": 7, + "VersionName": "1.4.2", "FriendlyName": "DungeonGenerator", "Description": "Procedural 3D dungeon generator plugin. Easy generation of levels, mini-maps and missions.", "Category": "Procedural", diff --git a/Source/DungeonGenerator/Private/Core/Generator.cpp b/Source/DungeonGenerator/Private/Core/Generator.cpp index 384d6e0..4c897f5 100644 --- a/Source/DungeonGenerator/Private/Core/Generator.cpp +++ b/Source/DungeonGenerator/Private/Core/Generator.cpp @@ -807,19 +807,19 @@ namespace dungeon // 部屋を生成 for (const auto& room : mRooms) { - const FIntVector min(room->GetLeft(), room->GetTop(), room->GetBackground()); - const FIntVector max(room->GetRight(), room->GetBottom(), room->GetForeground()); - mVoxel->Rectangle(min, max - , Grid::CreateFloor(parameter.GetRandom(), room->GetIdentifier().Get()) - , Grid::CreateDeck(parameter.GetRandom(), room->GetIdentifier().Get()) - ); - - const FVector center = (FVector(min) + FVector(max)) / 2; - const FVector dataSize(room->GetDataWidth(), room->GetDataDepth(), room->GetDataHeight()); - const FVector dataHalfSize = dataSize / 2; - const FIntVector dataMin = FIntVector(center - dataHalfSize); - const FIntVector dataMax = dataMin + FIntVector(dataSize); - mVoxel->NoMeshGeneration(dataMin, dataMax, room->IsNoRoofMeshGeneration(), room->IsNoFloorMeshGeneration()); + { + const FIntVector min(room->GetLeft(), room->GetTop(), room->GetBackground()); + const FIntVector max(room->GetRight(), room->GetBottom(), room->GetForeground()); + mVoxel->Rectangle(min, max + , Grid::CreateFloor(parameter.GetRandom(), room->GetIdentifier().Get()) + , Grid::CreateDeck(parameter.GetRandom(), room->GetIdentifier().Get()) + ); + } + { + FIntVector min, max; + room->GetDataBounds(min, max); + mVoxel->NoMeshGeneration(min, max, room->IsNoRoofMeshGeneration(), room->IsNoFloorMeshGeneration()); + } } // 通路の距離が短い順に並べ替える diff --git a/Source/DungeonGenerator/Private/Core/Room.cpp b/Source/DungeonGenerator/Private/Core/Room.cpp index 92d1c92..08bb3cb 100644 --- a/Source/DungeonGenerator/Private/Core/Room.cpp +++ b/Source/DungeonGenerator/Private/Core/Room.cpp @@ -299,4 +299,25 @@ namespace dungeon }; return names[static_cast(mItem)]; } + + FIntVector Room::GetDataSize() const noexcept + { + return FIntVector(mDataWidth, mDataDepth, mDataHeight); + } + + void Room::SetDataSize(const uint32_t dataWidth, const uint32_t dataDepth, const uint32_t dataHeight) + { + mDataWidth = dataWidth; + mDataDepth = dataDepth; + mDataHeight = dataHeight; + } + + void Room::GetDataBounds(FIntVector& min, FIntVector& max) const noexcept + { + const FIntVector center(GetGroundCenter()); + const FIntVector size = GetDataSize(); + const FIntVector offset(size.X / 2, size.Y / 2, 0); + min = center - offset; + max = min + size; + } } diff --git a/Source/DungeonGenerator/Private/Core/Room.h b/Source/DungeonGenerator/Private/Core/Room.h index 0d37ab9..75331df 100644 --- a/Source/DungeonGenerator/Private/Core/Room.h +++ b/Source/DungeonGenerator/Private/Core/Room.h @@ -294,33 +294,39 @@ namespace dungeon - uint32_t GetDataWidth() const noexcept { return mDataWidth; } - uint32_t GetDataDepth() const noexcept { return mDataDepth; } - uint32_t GetDataHeight() const noexcept { return mDataHeight; } + /* + Get the size of the mesh generation prohibited area + */ + FIntVector GetDataSize() const noexcept; - void SetDataSize(const uint32_t dataWidth, const uint32_t dataDepth, const uint32_t dataHeight) - { - mDataWidth = dataWidth; - mDataDepth = dataDepth; - mDataHeight = dataHeight; - } + /* + Set the size of the mesh generation prohibited area + */ + void SetDataSize(const uint32_t dataWidth, const uint32_t dataDepth, const uint32_t dataHeight); + + /* + Get mesh generation prohibited area + \param[out] min Minimum Position + \param[out] max Maximum position + */ + void GetDataBounds(FIntVector& min, FIntVector& max) const noexcept; /** - メッシュ生成禁止に設定します - \param[in] noRoofMeshGeneration 天井のメッシュ生成禁止 - \param[in] noFloorMeshGeneration 床のメッシュ生成禁止 + Sets mesh generation prohibition + \param[in] noRoofMeshGeneration No roof mesh generation + \param[in] noFloorMeshGeneration No floor mesh generation */ void SetNoMeshGeneration(const bool noRoofMeshGeneration, const bool noFloorMeshGeneration); /** - 床のメッシュ生成禁止か取得します - \return trueならメッシュ生成禁止 + Floor mesh generation is prohibited or acquired. + \return If true, mesh generation is prohibited */ bool IsNoFloorMeshGeneration() const noexcept; /** - 天井のメッシュ生成禁止か取得します - \return trueならメッシュ生成禁止 + Mesh generation of the ceiling is prohibited or acquired. + \return If true, mesh generation is prohibited */ bool IsNoRoofMeshGeneration() const noexcept; diff --git a/Source/DungeonGenerator/Private/DungeonGeneratorCore.cpp b/Source/DungeonGenerator/Private/DungeonGeneratorCore.cpp index 41f84ba..2570cdf 100644 --- a/Source/DungeonGenerator/Private/DungeonGeneratorCore.cpp +++ b/Source/DungeonGenerator/Private/DungeonGeneratorCore.cpp @@ -36,7 +36,7 @@ All Rights Reserved. // 定義するとミッショングラフのデバッグファイル(PlantUML)を出力します #define DEBUG_GENERATE_MISSION_GRAPH_FILE -static const FName DungeonGeneratorTag("DungeonGenerator"); +static const FName DungeonGeneratorTag(TEXT("DungeonGenerator")); namespace { @@ -191,19 +191,18 @@ bool CDungeonGeneratorCore::CreateImpl_AddRoomAsset(const UDungeonGenerateParame break; } - FVector centerPosition = room->GetGroundCenter() * parameter->GetGridSize(); - if ((room->GetWidth() & 1) != (dungeonRoomLocator.GetWidth() & 1)) - { - centerPosition.X += parameter->GetGridSize() / 2; - } - if ((room->GetDepth() & 1) != (dungeonRoomLocator.GetDepth() & 1)) - { - centerPosition.Y += parameter->GetGridSize() / 2; - } - if (RequestStreamLevel(dungeonRoomLocator.GetLevelPath(), centerPosition)) + if (!IsStreamLevelRequested(dungeonRoomLocator.GetLevelPath())) { room->SetDataSize(dungeonRoomLocator.GetWidth(), dungeonRoomLocator.GetDepth(), dungeonRoomLocator.GetHeight()); + + FIntVector min, max; + room->GetDataBounds(min, max); room->SetNoMeshGeneration(!dungeonRoomLocator.IsGenerateRoofMesh(), !dungeonRoomLocator.IsGenerateFloorMesh()); + + const float halfGridSize = parameter->GetGridSize() * 0.5f; + const FVector halfOffset(halfGridSize, halfGridSize, 0); + + RequestStreamLevel(dungeonRoomLocator.GetLevelPath(), FVector(min) * parameter->GetGridSize() + halfOffset); } }); @@ -230,7 +229,7 @@ void CDungeonGeneratorCore::AddTerrain() const size_t gridIndex = mGenerator->GetVoxel()->Index(location); const float gridSize = parameter->GetGridSize(); const float halfGridSize = gridSize * 0.5f; - const FVector halfOffset = FVector(halfGridSize, halfGridSize, 0); + const FVector halfOffset(halfGridSize, halfGridSize, 0); const FVector position = parameter->ToWorld(location); const FVector centerPosition = position + halfOffset; @@ -1013,19 +1012,19 @@ std::shared_ptr CDungeonGeneratorCore::GetGenerator() } //////////////////////////////////////////////////////////////////////////////////////////////////// -bool CDungeonGeneratorCore::RequestStreamLevel(const FSoftObjectPath& levelPath, const FVector& levelLocation) +bool CDungeonGeneratorCore::IsStreamLevelRequested(const FSoftObjectPath& levelPath) const { const auto requestStreamLevel = std::find_if(mRequestLoadStreamLevels.begin(), mRequestLoadStreamLevels.end(), [&levelPath](const LoadStreamLevelParameter& requestStreamLevel) { return requestStreamLevel.mPath == levelPath; } ); - if (requestStreamLevel != mRequestLoadStreamLevels.end()) - return false; + return requestStreamLevel != mRequestLoadStreamLevels.end(); +} +void CDungeonGeneratorCore::RequestStreamLevel(const FSoftObjectPath& levelPath, const FVector& levelLocation) +{ mRequestLoadStreamLevels.emplace_back(levelPath, levelLocation); - - return true; } void CDungeonGeneratorCore::AsyncLoadStreamLevels() @@ -1040,11 +1039,30 @@ void CDungeonGeneratorCore::AsyncLoadStreamLevels() UWorld* world = mWorld.Get(); if (IsValid(world)) { + bool bSuccess = false; +#if UE_VERSION_NEWER_THAN(5, 1, 0) const FTransform transform(FRotator::ZeroRotator, requestStreamLevel.mLocation); ULevelStreamingDynamic::FLoadLevelInstanceParams parameter(world, requestStreamLevel.mPath.GetLongPackageName(), transform); parameter.OptionalLevelStreamingClass = UDungeonLevelStreamingDynamic::StaticClass(); - bool bSuccess = false; ULevelStreamingDynamic* levelStreaming = ULevelStreamingDynamic::LoadLevelInstance(parameter, bSuccess); +#elif UE_VERSION_NEWER_THAN(5, 0, 0) + ULevelStreamingDynamic* levelStreaming = ULevelStreamingDynamic::LoadLevelInstance( + world, + requestStreamLevel.mPath.GetLongPackageName(), + requestStreamLevel.mLocation, + FRotator::ZeroRotator, + bSuccess, + TEXT(""), + UDungeonLevelStreamingDynamic::StaticClass(), + false); +#else + ULevelStreamingDynamic* levelStreaming = ULevelStreamingDynamic::LoadLevelInstance( + world, + requestStreamLevel.mPath.GetLongPackageName(), + requestStreamLevel.mLocation, + FRotator::ZeroRotator, + bSuccess); +#endif if (bSuccess && IsValid(levelStreaming)) { mLoadedStreamLevels.Add(levelStreaming); @@ -1060,6 +1078,7 @@ void CDungeonGeneratorCore::AsyncLoadStreamLevels() } } +#if WITH_EDITOR void CDungeonGeneratorCore::SyncLoadStreamLevels() { UWorld* world = mWorld.Get(); @@ -1072,11 +1091,31 @@ void CDungeonGeneratorCore::SyncLoadStreamLevels() if (FindLoadedStreamLevel(requestStreamLevel.mPath)) continue; + bool bSuccess = false; + +#if UE_VERSION_NEWER_THAN(5, 1, 0) const FTransform transform(FRotator::ZeroRotator, requestStreamLevel.mLocation); ULevelStreamingDynamic::FLoadLevelInstanceParams parameter(world, requestStreamLevel.mPath.GetLongPackageName(), transform); parameter.OptionalLevelStreamingClass = UDungeonLevelStreamingDynamic::StaticClass(); - bool bSuccess = false; ULevelStreamingDynamic* levelStreaming = ULevelStreamingDynamic::LoadLevelInstance(parameter, bSuccess); +#elif UE_VERSION_NEWER_THAN(5, 0, 0) + ULevelStreamingDynamic* levelStreaming = ULevelStreamingDynamic::LoadLevelInstance( + world, + requestStreamLevel.mPath.GetLongPackageName(), + requestStreamLevel.mLocation, + FRotator::ZeroRotator, + bSuccess, + TEXT(""), + UDungeonLevelStreamingDynamic::StaticClass(), + false); +#else + ULevelStreamingDynamic* levelStreaming = ULevelStreamingDynamic::LoadLevelInstance( + world, + requestStreamLevel.mPath.GetLongPackageName(), + requestStreamLevel.mLocation, + FRotator::ZeroRotator, + bSuccess); +#endif if (bSuccess && IsValid(levelStreaming)) { levelStreaming->bShouldBlockOnLoad = true; @@ -1086,17 +1125,19 @@ void CDungeonGeneratorCore::SyncLoadStreamLevels() ULevel* loadedLevel = levelStreaming->GetLoadedLevel(); if (IsValid(loadedLevel)) { -#if WITH_EDITOR - FString path, filename, extension; - FPaths::Split(levelStreaming->PackageNameToLoad.ToString(), path, filename, extension); -#endif + FString folder = levelStreaming->PackageNameToLoad.ToString(); + folder.RemoveFromStart("/Game/", ESearchCase::IgnoreCase); + folder.RemoveFromStart("Map/", ESearchCase::IgnoreCase); + folder.RemoveFromStart("Maps/", ESearchCase::IgnoreCase); + folder.RemoveFromStart("Level/", ESearchCase::IgnoreCase); + folder.RemoveFromStart("Levels/", ESearchCase::IgnoreCase); + for (AActor* actor : loadedLevel->Actors) { actor->Tags.Add(GetDungeonGeneratorTag()); -#if WITH_EDITOR - const FName folderPath(FString(TEXT("Dungeon/Levels/")) + filename); + + const FName folderPath(FString(TEXT("Dungeon/Levels/")) + folder); actor->SetFolderPath(folderPath); -#endif } moveActors.Append(loadedLevel->Actors); @@ -1120,10 +1161,11 @@ void CDungeonGeneratorCore::SyncLoadStreamLevels() mRequestLoadStreamLevels.clear(); } } +#endif void CDungeonGeneratorCore::UnloadStreamLevels() { - SyncLoadStreamLevels(); + mRequestLoadStreamLevels.clear(); UWorld* world = mWorld.Get(); if (IsValid(world)) @@ -1136,38 +1178,60 @@ void CDungeonGeneratorCore::UnloadStreamLevels() } } -void CDungeonGeneratorCore::UnloadStreamLevel(const FSoftObjectPath& levelPath) +TSoftObjectPtr CDungeonGeneratorCore::FindLoadedStreamLevel(const FSoftObjectPath& levelPath) const { - SyncLoadStreamLevels(); - - UWorld* world = mWorld.Get(); - if (IsValid(world)) + for (const TSoftObjectPtr& loadedStreamLevel : mLoadedStreamLevels) { - for (int32 i = 0; i < mLoadedStreamLevels.Num(); ++i) + if (loadedStreamLevel.IsValid()) { - const TSoftObjectPtr& loadedStreamLevel = mLoadedStreamLevels[i]; +#if UE_VERSION_OLDER_THAN(5, 1, 0) if (loadedStreamLevel->PackageNameToLoad == levelPath.GetAssetPathName()) +#else + if (loadedStreamLevel->PackageNameToLoad == levelPath.GetAssetPath().GetPackageName()) +#endif { - world->RemoveStreamingLevel(loadedStreamLevel.Get()); - - mLoadedStreamLevels.RemoveAt(i); - break; + return loadedStreamLevel; } } } + return nullptr; } -TSoftObjectPtr CDungeonGeneratorCore::FindLoadedStreamLevel(const FSoftObjectPath& levelPath) const +void CDungeonGeneratorCore::LoadStreamLevelImplement(UWorld* world, const FSoftObjectPath& path, const FTransform& transform) { - for (const TSoftObjectPtr& loadedStreamLevel : mLoadedStreamLevels) +#if UE_VERSION_NEWER_THAN(5, 0, 0) + const FName& longPackageName = path.GetLongPackageFName(); +#else + const FName& longPackageName = FName(path.GetLongPackageName()); +#endif + ULevelStreaming* levelStreaming; + + levelStreaming = UGameplayStatics::GetStreamingLevel(world, longPackageName); + if (IsValid(levelStreaming)) { - if (loadedStreamLevel.IsValid()) - { - if (loadedStreamLevel->PackageNameToLoad == levelPath.GetAssetPathName()) - return loadedStreamLevel; - } + UnloadStreamLevelImplement(world, path, true); } - return nullptr; + + FLatentActionInfo LatentInfo; + UGameplayStatics::LoadStreamLevel(world, longPackageName, false, false, LatentInfo); + + levelStreaming = UGameplayStatics::GetStreamingLevel(world, longPackageName); + if (IsValid(levelStreaming)) + { + levelStreaming->LevelTransform = transform; + levelStreaming->SetShouldBeVisible(true); + } +} + +void CDungeonGeneratorCore::UnloadStreamLevelImplement(UWorld* world, const FSoftObjectPath& path, const bool shouldBlockOnUnload) +{ +#if UE_VERSION_NEWER_THAN(5, 0, 0) + const FName& longPackageName = path.GetLongPackageFName(); +#else + const FName& longPackageName = FName(path.GetLongPackageName()); +#endif + FLatentActionInfo LatentInfo; + UGameplayStatics::UnloadStreamLevel(world, longPackageName, LatentInfo, shouldBlockOnUnload); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Source/DungeonGenerator/Private/DungeonLevelStreamingActor.cpp b/Source/DungeonGenerator/Private/DungeonLevelStreamingActor.cpp new file mode 100644 index 0000000..9c035ba --- /dev/null +++ b/Source/DungeonGenerator/Private/DungeonLevelStreamingActor.cpp @@ -0,0 +1,63 @@ +/** +\author Shun Moriya +\copyright 2023- Shun Moriya +All Rights Reserved. +*/ + +#include "DungeonLevelStreamingActor.h" +#include +#include +#include +#include + +ADungeonLevelStreamingActor::ADungeonLevelStreamingActor(const FObjectInitializer& initializer) + : Super(initializer) +{ + PrimaryActorTick.bCanEverTick = true; + + OverlapVolume = CreateDefaultSubobject(TEXT("OverlapVolume")); + OverlapVolume->OnComponentBeginOverlap.AddUniqueDynamic(this, &ADungeonLevelStreamingActor::OverlapBegins); + OverlapVolume->OnComponentEndOverlap.AddUniqueDynamic(this, &ADungeonLevelStreamingActor::OverlapEnds); + RootComponent = OverlapVolume; +} + +void ADungeonLevelStreamingActor::OverlapBegins(UPrimitiveComponent* overlappedComponent, AActor* otherActor, UPrimitiveComponent* otherComp, int32 otherBodyIndex, bool fromSweep, const FHitResult& sweepResult) +{ + if (Path.IsValid()) + { + ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); + if (otherActor == Cast(MyCharacter)) + { +#if UE_VERSION_NEWER_THAN(5, 0, 0) + const FName& longPackageName = Path.GetLongPackageFName(); +#else + const FName& longPackageName = FName(Path.GetLongPackageName()); +#endif + FLatentActionInfo LatentInfo; + UGameplayStatics::LoadStreamLevel(this, longPackageName, true, true, LatentInfo); +#if 0 + ULevelStreaming* level = UGameplayStatics::GetStreamingLevel(GetWorld(), LevelToLoad); + level->LevelTransform = GetTransform(); + level->SetShouldBeVisible(true); +#endif + } + } +} + +void ADungeonLevelStreamingActor::OverlapEnds(UPrimitiveComponent* overlappedComponent, AActor* otherActor, UPrimitiveComponent* otherComp, int32 otherBodyIndex) +{ + if (Path.IsValid()) + { + ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); + if (otherActor == Cast(MyCharacter)) + { +#if UE_VERSION_NEWER_THAN(5, 0, 0) + const FName& longPackageName = Path.GetLongPackageFName(); +#else + const FName& longPackageName = FName(Path.GetLongPackageName()); +#endif + FLatentActionInfo LatentInfo; + UGameplayStatics::UnloadStreamLevel(this, longPackageName, LatentInfo, false); + } + } +} diff --git a/Source/DungeonGenerator/Private/DungeonLevelStreamingDynamic.cpp b/Source/DungeonGenerator/Private/DungeonLevelStreamingDynamic.cpp index cbfbf8f..149b494 100644 --- a/Source/DungeonGenerator/Private/DungeonLevelStreamingDynamic.cpp +++ b/Source/DungeonGenerator/Private/DungeonLevelStreamingDynamic.cpp @@ -1,3 +1,9 @@ +/** +\author Shun Moriya +\copyright 2023- Shun Moriya +All Rights Reserved. +*/ + #include "DungeonLevelStreamingDynamic.h" UDungeonLevelStreamingDynamic::UDungeonLevelStreamingDynamic(const FObjectInitializer& initializer) diff --git a/Source/DungeonGenerator/Public/DungeonGenerateParameter.h b/Source/DungeonGenerator/Public/DungeonGenerateParameter.h index c5477cc..013ff41 100644 --- a/Source/DungeonGenerator/Public/DungeonGenerateParameter.h +++ b/Source/DungeonGenerator/Public/DungeonGenerateParameter.h @@ -374,15 +374,15 @@ class DUNGEONGENERATOR_API UDungeonGenerateParameter : public UObject TArray DoorParts; // Move PlayerStart to the starting point. - UPROPERTY(EditAnywhere, Category = "DungeonGenerator|Door", BlueprintReadWrite) + UPROPERTY(EditAnywhere, Category = "DungeonGenerator|Start", BlueprintReadWrite) bool MovePlayerStartToStartingPoint = true; // starting point - UPROPERTY(EditAnywhere, Category = "DungeonGenerator", BlueprintReadWrite) + UPROPERTY(EditAnywhere, Category = "DungeonGenerator|Start", BlueprintReadWrite) FDungeonActorPartsWithDirection StartParts; // goal position - UPROPERTY(EditAnywhere, Category = "DungeonGenerator", BlueprintReadWrite) + UPROPERTY(EditAnywhere, Category = "DungeonGenerator|Goal", BlueprintReadWrite) FDungeonActorPartsWithDirection GoalParts; // Room Sensor Class diff --git a/Source/DungeonGenerator/Public/DungeonGeneratorCore.h b/Source/DungeonGenerator/Public/DungeonGeneratorCore.h index 95a8350..91cb69a 100644 --- a/Source/DungeonGenerator/Public/DungeonGeneratorCore.h +++ b/Source/DungeonGenerator/Public/DungeonGeneratorCore.h @@ -178,13 +178,18 @@ class DUNGEONGENERATOR_API CDungeonGeneratorCore final : public std::enable_shar template const T* FindActor() const; //////////////////////////////////////////////////////////////////////////// - bool RequestStreamLevel(const FSoftObjectPath& levelPath, const FVector& levelLocation); + bool IsStreamLevelRequested(const FSoftObjectPath& levelPath) const; + void RequestStreamLevel(const FSoftObjectPath& levelPath, const FVector& levelLocation); void AsyncLoadStreamLevels(); +#if WITH_EDITOR void SyncLoadStreamLevels(); +#endif void UnloadStreamLevels(); - void UnloadStreamLevel(const FSoftObjectPath& levelPath); TSoftObjectPtr FindLoadedStreamLevel(const FSoftObjectPath& levelPath) const; + void LoadStreamLevelImplement(UWorld* world, const FSoftObjectPath& path, const FTransform& transform); + void UnloadStreamLevelImplement(UWorld* world, const FSoftObjectPath& path, const bool shouldBlockOnUnload); + //////////////////////////////////////////////////////////////////////////// UTexture2D* GenerateMiniMapTexture(uint32_t worldToTextureScale, uint32_t textureWidthHeight, uint32_t currentLevel) const; diff --git a/Source/DungeonGenerator/Public/DungeonLevelStreamingActor.h b/Source/DungeonGenerator/Public/DungeonLevelStreamingActor.h new file mode 100644 index 0000000..9b0135f --- /dev/null +++ b/Source/DungeonGenerator/Public/DungeonLevelStreamingActor.h @@ -0,0 +1,49 @@ +/** +\author Shun Moriya +\copyright 2023- Shun Moriya +All Rights Reserved. +*/ + +#pragma once + +#include +#include "DungeonLevelStreamingActor.generated.h" + +class UBoxComponent; + +/* +vC[OverlapVolumeɓɎw背x[hwp[NX + +*/ +UCLASS(Blueprintable, BlueprintType) +class DUNGEONGENERATOR_API ADungeonLevelStreamingActor : public AActor +{ + GENERATED_BODY() + +public: + /* + constructor + */ + explicit ADungeonLevelStreamingActor(const FObjectInitializer& initializer); + + /* + destructor + */ + virtual ~ADungeonLevelStreamingActor() = default; + +protected: + UFUNCTION() + void OverlapBegins(UPrimitiveComponent* overlappedComponent, AActor* otherActor, UPrimitiveComponent* otherComp, int32 otherBodyIndex, bool fromSweep, const FHitResult& sweepResult); + + UFUNCTION() + void OverlapEnds(UPrimitiveComponent* overlappedComponent, AActor* otherActor, UPrimitiveComponent* otherComp, int32 otherBodyIndex); + +protected: + // Overlap volume to trigger level streaming + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "DungeonGenerator") + UBoxComponent* OverlapVolume; + + // Level streaming path + UPROPERTY(EditAnywhere, Category = "DungeonGenerator", meta = (AllowedClasses = "World")) + FSoftObjectPath Path; +}; diff --git a/Source/DungeonGenerator/Public/DungeonLevelStreamingDynamic.h b/Source/DungeonGenerator/Public/DungeonLevelStreamingDynamic.h index 69e2cc7..f879e72 100644 --- a/Source/DungeonGenerator/Public/DungeonLevelStreamingDynamic.h +++ b/Source/DungeonGenerator/Public/DungeonLevelStreamingDynamic.h @@ -1,3 +1,9 @@ +/** +\author Shun Moriya +\copyright 2023- Shun Moriya +All Rights Reserved. +*/ + #pragma once #include