Announcement

Collapse
No announcement yet.

Dungeon Architect

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    I've got world composition supported in the snap builder

    However there's a limitation. The engine doesn't allow me to stream the same level multiple times. One level can be stream only once at a particular location. This doesn't work as we might need to spawn a module (like corridor/room) multiple times across the map

    As a workaround, I'll create a folder in the same location as the base map, then make a copy of each module map into that folder and stream that in, this way each modules copy is unique


    Foliage works properly with the new world composition system

    I added grass on the spawn module. It shows up properly on the generated map
    Dungeon Architect | Prefabricator

    Discord Support

    Comment


      Thanks again Ali, super fast and useful answer !

      I'll definitely check Visual Assist, it's the not first time i hear about it^^

      Comment


        I made a simple city builder for the unity version a while ago. It is a basic grid based rectangular road network with proper markers to setup roads (T junctions, X junctions, etc), buildings facing streets, parks in the middle

        I'll bring it to UE4 soon



        Dungeon Architect | Prefabricator

        Discord Support

        Comment


          That's settled it. Buying on payday. ^_^

          Comment


            Originally posted by Ali Akbar View Post
            I made a simple city builder for the unity version a while ago. It is a basic grid based rectangular road network with proper markers to setup roads (T junctions, X junctions, etc), buildings facing streets, parks in the middle

            I'll bring it to UE4 soon
            woaw, that's realy a great news. I'm looking forward to play with this

            Comment


              Originally posted by Ali Akbar View Post
              I made a simple city builder for the unity version a while ago. It is a basic grid based rectangular road network with proper markers to setup roads (T junctions, X junctions, etc), buildings facing streets, parks in the middle

              I'll bring it to UE4 soon
              That looks really interesting. Will this replace City Architect or do you still plan on finishing it?

              Comment


                Originally posted by Sitrec View Post
                That looks really interesting. Will this replace City Architect or do you still plan on finishing it?
                I plan on finishing it with OpenStreetMap. I was looking at the OSM Overpass API and the protocol specs recently
                Dungeon Architect | Prefabricator

                Discord Support

                Comment


                  The world composition method is too restrictive. The workaround would make it work only in the editor (as cloning of worlds is part of the editor API). I'm looking at fixing the original spawn code
                  Dungeon Architect | Prefabricator

                  Discord Support

                  Comment


                    Originally posted by Ali Akbar View Post
                    The world composition method is too restrictive. The workaround would make it work only in the editor (as cloning of worlds is part of the editor API). I'm looking at fixing the original spawn code
                    Hi (Merhaba) Ali,

                    I'm just not sure but please look at https://forums.unrealengine.com/show...ll=1#post18007 Probably this is what you want (Spawn same sub-level more than once.)

                    Comment


                      Originally posted by Ali Akbar View Post
                      I made a simple city builder for the unity version a while ago. It is a basic grid based rectangular road network with proper markers to setup roads (T junctions, X junctions, etc), buildings facing streets, parks in the middle

                      I'll bring it to UE4 soon



                      I was wondering when this would come to unreal engine.

                      Will we be able to use theme files like normal with the city builder? If so...

                      Click image for larger version

Name:	Sales-Funnel-Shut-Up-and-Take-My-Money2.jpg
Views:	1
Size:	62.5 KB
ID:	1115859

                      Comment


                        Originally posted by Ali Akbar View Post
                        I made a simple city builder for the unity version a while ago. It is a basic grid based rectangular road network with proper markers to setup roads (T junctions, X junctions, etc), buildings facing streets, parks in the middle

                        I'll bring it to UE4 soon



                        o.o Your Awesome... I spent 3 Years developing a Procedurally generated game in unity, City, Building, @.@ and had to Switch to unreal engine :X I cant wait to buy this. Lolz

                        Comment


                          So - Just got looking at the tutorial videos on YouTube for Dungeon Architect. Looks like I would have to define a Base City theme and then define a bunch of sub themes and overwrite the various bits of city that I want with them override volumes.

                          That said - The ability to connect multiple dungeons (or in my case Cities) together would be great. Would that be possible? I think that would be a great way to circumvent the problem you are facing with World Composition. So basically make the City Builder have an entrance or Exit which an artist can make it connect to another level manually.

                          Either way just a thought.

                          - HeadClot
                          Last edited by HeadClot; 09-24-2016, 10:53 PM.

                          Comment


                            Originally posted by HeadClot View Post
                            So - Just got looking at the tutorial videos on YouTube for Dungeon Architect. Looks like I would have to define a Base City theme and then define a bunch of sub themes and overwrite the various bits of city that I want with them override volumes.

                            That said - The ability to connect multiple dungeons (or in my case Cities) together would be great. Would that be possible? I think that would be a great way to circumvent the problem you are facing with World Composition. So basically make the City Builder have an entrance or Exit which an artist can make it connect to another level manually.

                            Either way just a thought.

                            - HeadClot
                            [MENTION=260]HeadClot[/MENTION] that should be possible. I'll have a demo of this soon and I'm open to suggestions
                            Dungeon Architect | Prefabricator

                            Discord Support

                            Comment


                              Originally posted by MSTF View Post
                              Hi (Merhaba) Ali,

                              I'm just not sure but please look at https://forums.unrealengine.com/show...ll=1#post18007 Probably this is what you want (Spawn same sub-level more than once.)
                              Thank you [MENTION=22103]MSTF[/MENTION]. That is very useful. This works during runtime, however the editor gives errors since we change the package names as a workaround in that thread. So I've made two implementations, one for the editor and another for the runtime. If it is a runtime only build (e.g. standalone game) it would use the implementation mentioned in the thread. If we are in the editor, I use the editor services to clone the level files and map them to the world composition so we don't get any warnings in the editor

                              This way it solves the problem in both editor and non-editor builds

                              Here's the code, if anyone is interested on getting something like this done


                              Non-Editor Builds (e.g. standalone)
                              Code:
                              ULevel* FDungeonNonEditorFallbackService::CreateStreamingLevelInstance(UWorld* InWorld, const FTransform& Transform, const TAssetPtr<UWorld>& WorldAsset, UClass* LevelStreamingClass) {
                              	ULevel* NewLevel = NULL;
                              	if (LevelStreamingClass == NULL) {
                              		return NULL;
                              	}
                              
                              	ULevelStreaming* StreamingLevel = NewObject<ULevelStreaming>(InWorld, LevelStreamingClass, NAME_None, RF_NoFlags, NULL);
                              
                              	FString PackageName = WorldAsset.GetLongPackageName();
                              	FString UniquePackageName = PackageName + "_" + FGuid::NewGuid().ToString();
                              	StreamingLevel->SetWorldAssetByPackageName(FName(*UniquePackageName));
                              
                              	StreamingLevel->LevelTransform = Transform;
                              	StreamingLevel->PackageNameToLoad = FName(*PackageName);
                              	StreamingLevel->bShouldBeLoaded = true;
                              	StreamingLevel->bShouldBeVisible = true;
                              	StreamingLevel->bShouldBlockOnLoad = false;
                              	StreamingLevel->LevelColor = FLinearColor::MakeRandomColor();
                              
                              	// Add the new level to world.
                              	InWorld->StreamingLevels.Add(StreamingLevel);
                              
                              	// Refresh just the newly created level.
                              	TArray<ULevelStreaming*> LevelsForRefresh;
                              	LevelsForRefresh.Add(StreamingLevel);
                              	InWorld->RefreshStreamingLevels(LevelsForRefresh);
                              	InWorld->MarkPackageDirty();
                              
                              	NewLevel = StreamingLevel->GetLoadedLevel();
                              	if (NewLevel != nullptr)
                              	{
                              		//EditorLevelUtils::SetLevelVisibility(NewLevel, true, true);
                              
                              		// Levels migrated from other projects may fail to load their world settings
                              		// If so we create a new AWorldSettings actor here.
                              		if (NewLevel->GetWorldSettings(false) == nullptr)
                              		{
                              			UWorld* SubLevelWorld = CastChecked<UWorld>(NewLevel->GetOuter());
                              
                              			FActorSpawnParameters SpawnInfo;
                              			SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
                              			SpawnInfo.Name = GEngine->WorldSettingsClass->GetFName();
                              			AWorldSettings* NewWorldSettings = SubLevelWorld->SpawnActor<AWorldSettings>(GEngine->WorldSettingsClass, SpawnInfo);
                              
                              			NewLevel->SetWorldSettings(NewWorldSettings);
                              		}
                              	}
                              
                              	return NewLevel;
                              }

                              Editor Builds
                              Code:
                              	template<typename T>
                              	static T* CloneAsset(const FString& TemplatePath, const FString& TargetName, const FString& TargetDirectory) {
                              		T* Template = LoadObject<T>(NULL, *TemplatePath, NULL, LOAD_None, NULL);
                              		IAssetTools& AssetTools = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools").Get();
                              		UObject* AssetObject = AssetTools.DuplicateAsset(TargetName, TargetDirectory, Template);
                              		T* Asset = Cast<T>(AssetObject);
                              		if (!Asset) {
                              			UE_LOG(LogEditorService, Warning, TEXT("Failed to clone asset at location %s/%s"), *TargetDirectory, *TargetName);
                              		}
                              		return Asset;
                              	}
                              
                              
                              ULevel* FDungeonEditorService::CreateStreamingLevelInstance(UWorld* InWorld, const FTransform& Transform, const TAssetPtr<UWorld>& WorldAsset, UClass* LevelStreamingClass)
                              {
                              	ULevel* NewLevel = nullptr;
                              	if (LevelStreamingClass == NULL) {
                              		return NULL;
                              	}
                              
                              	ULevelStreaming* StreamingLevel = NewObject<ULevelStreaming>(InWorld, LevelStreamingClass, NAME_None, RF_NoFlags, NULL);
                              
                              	// Clone the streaming world
                              	if (!InWorld || !InWorld->GetOutermost()) {
                              		UE_LOG(LogEditorService, Error, TEXT("Cannot create streaming level.  World context state is invalid"));
                              		return nullptr;
                              	}
                              
                              	FString ClonedAssetName = WorldAsset->GetName() + "_" + FGuid::NewGuid().ToString();
                              	FString ClonedAssetPath = InWorld->GetOutermost()->GetName() + "_SnapStreamingInstances";
                              	UWorld* ClonedWorld = CloneAsset<UWorld>(WorldAsset.GetLongPackageName(), ClonedAssetName, ClonedAssetPath);
                              	if (!ClonedWorld) {
                              		UE_LOG(LogEditorService, Error, TEXT("Failed to clone snap module"));
                              		return nullptr;
                              	}
                              	FStringAssetReference ClonedWorldAssetRef(ClonedWorld);
                              	FString ClonedWorldPath = ClonedWorldAssetRef.ToString();
                              	StreamingLevel->SetWorldAssetByPackageName(FName(*ClonedWorldPath));
                              
                              	StreamingLevel->LevelTransform = Transform;
                              	StreamingLevel->bShouldBeLoaded = true;
                              	StreamingLevel->bShouldBeVisible = true;
                              	StreamingLevel->bShouldBlockOnLoad = false;
                              	StreamingLevel->LevelColor = FLinearColor::MakeRandomColor();
                              
                              	// Add the new level to world.
                              	InWorld->StreamingLevels.Add(StreamingLevel);
                              
                              	// Refresh just the newly created level.
                              	TArray<ULevelStreaming*> LevelsForRefresh;
                              	LevelsForRefresh.Add(StreamingLevel);
                              	InWorld->RefreshStreamingLevels(LevelsForRefresh);
                              	InWorld->MarkPackageDirty();
                              
                              	NewLevel = StreamingLevel->GetLoadedLevel();
                              	if (NewLevel != nullptr)
                              	{
                              		//EditorLevelUtils::SetLevelVisibility(NewLevel, true, true);
                              
                              		// Levels migrated from other projects may fail to load their world settings
                              		// If so we create a new AWorldSettings actor here.
                              		if (NewLevel->GetWorldSettings(false) == nullptr)
                              		{
                              			UWorld* SubLevelWorld = CastChecked<UWorld>(NewLevel->GetOuter());
                              
                              			FActorSpawnParameters SpawnInfo;
                              			SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
                              			SpawnInfo.Name = GEngine->WorldSettingsClass->GetFName();
                              			AWorldSettings* NewWorldSettings = SubLevelWorld->SpawnActor<AWorldSettings>(GEngine->WorldSettingsClass, SpawnInfo);
                              
                              			NewLevel->SetWorldSettings(NewWorldSettings);
                              		}
                              	}
                              
                              	return NewLevel;
                              }
                              Last edited by Ali Akbar; 09-25-2016, 03:49 AM. Reason: typo
                              Dungeon Architect | Prefabricator

                              Discord Support

                              Comment


                                Originally posted by Ali Akbar View Post
                                I've rewritten the data structure so you should have access to the graph data structure (to query other modules attached to a door)
                                Can you throw me a Example, I think i`m Doing something wrong @.@ Everything I`ve Tried, that should work for allocation of information/Actors/Meshes in the Route arent working -_-

                                Comment

                                Working...
                                X