View Issue Details

IDProjectCategoryView StatusLast Update
0005079NoesisGUIUnrealpublic2026-10-27 18:43
ReporterSillyGoose Assigned Tosfernandez  
PrioritynormalSeverityfeature 
Status assignedResolutionopen 
Product VersionStudio_Beta 
Target Version4.0.2 
Summary0005079: Add a method to allow use of multiple Studio projects/assembleys within a single module in Unreal
Description

Hey, we'd like a method of allowing us to have multiple projects/assmbleys under the same module in Unreal, in the latest Studio SDK. Currently we are still on 3.2.13, because we haven't been able to upgrade, due to the restriction that you can only have 1 project/assembly per module/plug-in in Unreal.

We've implemented several Studio projects, and have been using project references. We prefer this as we've found it more manageable to have more contained projects for areas of UI, and shared UI.

But, in the Studio beta (last tried in beta 6), it currently requires you to only use 1 assembly per module/plug-in. Covered in this Forum Post: https://www.noesisengine.com/forums/viewtopic.php?p=19228

It's been proposed that if you could expose Assembly's -> File paths in the Settings, then we could make it work. That would unlock us being able to work with multiple projects and the Studio Beta. Long term, maybe there's a way to make this automatic (scan the studio projects to gather that info?). I think this would unlock another way of working with Noesis and Unreal.

Thanks

PlatformAny

Relationships

related to 0005292 assignedsfernandez The order of the Studio project list under the NoesisGUI top menu is fixed 

Activities

jsantos

jsantos

2026-06-15 17:07

manager   ~0012364

We discussed adding a plugin setting for Unity and Unreal to allow custom assembly mappings

SillyGoose

SillyGoose

2026-10-20 17:46

reporter   ~0012781

Hey, I have added a patch (to v4.0.0), of an implementation allows us to work with how Studio adds resource paths at runtime (as project Uris). Previously we've had to manually add relative paths to make it work in both Studio & runtime e.g.

  <ResourceDictionary.MergedDictionaries>
  <!-- Works in Studio -->
    <ResourceDictionary Source="/SomeProject;component/XAML_SomeResource.xaml"/>
  <!-- Works in Unreal -->
    <ResourceDictionary Source="../../UI/SharedResources/XAML_SomeResource.xaml"/>
  </ResourceDictionary.MergedDictionaries>

The change sets up a Namespace -> Path Map in the settings, and then uses that when looking up Uris. This is manual process though. I haven't checked how expensive that may be, doing it every Uri look-up. Let me know if you think it's a viable solution, or if there's any issues you might think it to cause.

This is more just visibility of a part solution, I would still prefer your expertise on what a final solution may want to be.

This also only helps with the runtime, there are still issues around if you want to create new Studio projects with different namespaces within the current version of Studio within Unreal. For that we currently still have to do that in Standalone Studio.

Ideally we'd want to also improve the Unreal Studio side, such as:

  • Ability to create new projects under different namespaces (other than 'Game')
  • Able to have multiple projects open at once, instead of just 1.
  • Project list more manageable in-game i.e. most recent instead of fixed list shared by all.
CL1571386.patch (3,245 bytes)   
--- NoesisGUI/Source/NoesisRuntime/Classes/NoesisSettings.h	2026-10-09 12:29:51.000000000 0100
+++ NoesisGUI\Source\NoesisRuntime\Classes\NoesisSettings.h	2026-10-09 12:29:51.000000000 0100
@@ -11,6 +11,10 @@
 // CoreUObject includes
 #include "UObject/SoftObjectPtr.h"
 
+// @Custom
+#include "UObject/SoftObjectPath.h"
+// @~Custom
+
 // NoesisRuntime includes
 #include "NoesisEnums.h"
 
@@ -63,6 +67,22 @@
 	int Order = -1;
 };
 
+// @Custom
+USTRUCT()
+struct FStudioProjectAssemblyMapping
+{
+	GENERATED_USTRUCT_BODY()
+
+	/** The Noesis assembly name (as referenced by a Uri) to map to a content directory. */
+	UPROPERTY(EditAnywhere, Config, Category = Studio)
+	FString AssemblyName;
+
+	/** Content directory whose assets should resolve for this assembly. */
+	UPROPERTY(EditAnywhere, Config, Category = Studio, meta = (ContentDir))
+	FDirectoryPath Directory;
+};
+// @~Custom
+
 UCLASS(Config = Engine, DefaultConfig)
 class NOESISRUNTIME_API UNoesisSettings : public UObject
 {
@@ -108,6 +128,12 @@
 	UPROPERTY(EditAnywhere, Config, Category = "Studio")
 	TArray<FStudioProjectConfig> StudioProjects;
 
+// @Custom
+	/** Maps a Noesis assembly name to the content directory its assets are loaded from */
+	UPROPERTY(EditAnywhere, Config, Category = "Studio")
+	TArray<FStudioProjectAssemblyMapping> StudioProjectAssemblyMappings;
+// @~Custom
+
 	/** Dimensions of texture used to cache glyphs */
 	UPROPERTY(EditAnywhere, Config, Category = "Rendering", meta = (ConfigRestartRequired = true))
 	ENoesisGlyphCacheDimensions GlyphTextureSize;
--- NoesisGUI/Source/NoesisRuntime/Public/NoesisSupport.h	2026-05-01 13:13:58.000000000 0100
+++ NoesisGUI\Source\NoesisRuntime\Public\NoesisSupport.h	2026-05-01 13:13:58.000000000 0100
@@ -15,6 +15,11 @@
 // Noesis includes
 #include "NoesisSDK.h"
 
+// @Custom
+// NoesisRuntime includes
+#include "NoesisSettings.h"
+// @~Custom
+
 inline FString NsStringToFString(const char* String)
 {
 	return FString(StringCast<TCHAR>((UTF8CHAR*)String).Get());
@@ -70,9 +75,33 @@
 	Noesis::String Assembly;
 	Uri.GetAssembly(Assembly);
 
-	FString AssetPath = TEXT("/");
-	AssetPath += (UTF8CHAR*)GetAssetRoot(Assembly).Str();
-	AssetPath += TEXT("/") + SafePath;
+// @Custom
+	FString AssetPath;
+	
+	const FString AssemblyName = NsStringToFString(Assembly.Str());
+	const TArray<FStudioProjectAssemblyMapping>& StudioProjectAssemblyMappings = GetDefault<UNoesisSettings>()->StudioProjectAssemblyMappings;
+	const FStudioProjectAssemblyMapping* MappedEntry = StudioProjectAssemblyMappings.FindByPredicate([&AssemblyName](const FStudioProjectAssemblyMapping& Mapping)
+	{
+		return Mapping.AssemblyName == AssemblyName;
+	});
+	
+	if (MappedEntry != nullptr)
+	{
+		// Mapping found - use path defined in setting to map to
+		FString MappedPath = MappedEntry->Directory.Path;
+		if (!MappedPath.IsEmpty() && !MappedPath.EndsWith(TEXT("/")))
+		{
+			MappedPath += TEXT("/");
+		}
+		AssetPath = MappedPath + SafePath;
+	}
+	else
+	{
+		AssetPath += TEXT("/");
+		AssetPath += (UTF8CHAR*)GetAssetRoot(Assembly).Str();
+		AssetPath += TEXT("/") + SafePath;
+	}
+// @~Custom
 
 	return AssetPath;
 }
CL1571386.patch (3,245 bytes)   
NoesisAssemblyPaths.png (27,396 bytes)   
NoesisAssemblyPaths.png (27,396 bytes)   

Issue History

Date Modified Username Field Change
2026-06-15 11:23 SillyGoose New Issue
2026-06-15 17:05 jsantos Assigned To => sfernandez
2026-06-15 17:05 jsantos Status new => assigned
2026-06-15 17:05 jsantos Target Version => 4.0
2026-06-15 17:07 jsantos Note Added: 0012364
2026-10-20 17:46 SillyGoose Note Added: 0012781
2026-10-20 17:46 SillyGoose File Added: CL1571386.patch
2026-10-20 17:46 SillyGoose File Added: NoesisAssemblyPaths.png
2026-10-22 13:26 sfernandez Target Version 4.0 => 4.0.2
2026-10-27 18:43 sfernandez Relationship added related to 0005292