Resize viewport area so it won't take up the whole screen in packaged project

Hello,

at the moment I’m working on a little software that makes it easy to view assets.
The viewport area shouldn’t take up the whole screen, but only a certain part of it, so that the settings can be seen on the right and the timeline on the bottom.
But I can’t find a way to limit the size of the viewport so that the focus point is not in the middle of the screen but in the middle of the viewport.

Hopefully the image will make it a bit more understandable what I mean exactly. The red line represents the center of the viewport.

Gévarred

Hi @Gévarred

If you place settings in a widget it will be printed on the viewport anyway, no?
you need the viewport to be decentered? i am not sure but maybe is possible making your own class . dont know.

You can limit the size of the camera , selecting the camera in the actor and going in detail and Camera settings, you can find the Aspect ratio.
If you constrain and give her an aspect ratio of 1.7 you will get a Width of 1700 and an height of 1000.
Forcing the camera to lower aspect ratio like , 1, will result in a squared view, and 2 dark area will appear on the side of the view.
The view will be centered, i dont know if you can move it to the side.

Hello @Est_engine ,

Exactly, the viewport should be decentered. Just like it’s done in Maya, Substance Painter or in UE4 itself but it doesn’t have to be moveable.
Changing the aspect ratio has partly worked. Theoretically I would have enough space for the menu on the right, but on the left there is a black bar too and at the bottom there is no space for the animation timeline.

Hi @Gévarred

Well if you really want this kind of customization maybe you can use a 2d capture scene.
You need to create one of these 2d scene capture and a target render.
Than a material and feed the Target render into the material, Change the material domain from surface to userInterface.
Then make a widget , add an image and set the brush-image to the material you done.
This way you can set the Camera wherever you want in the widget space,
If you (like me) can see the target-render in the widget project but when you hit play it became white, play with the tint, i dont know why .

Is there any other way to achieve this other than with scene capture/render targets? Scene capture doesn’t capture lumen in UE5…

I’ve found a couple other threads asking about this same thing, but no good solutions…

I am now facing a similar problem and up to now I have found two different solutions to this.

Ofc the second approach is much more flexible, but if you want it to work without editor build, it will require a solid amount of work. Mostly three things:

  • Write your Draw() function for the custom FViewportClient.
  • You will need to create your Slate layout and assign it to a new window (Unreal forces the main window to contain the instantiated UGameViewport in SwitchGameWindowToUseGameViewport()). Ofc you can create the layout in UMG, but some custom UUserWidget is required.
  • Be sure input and such correctly work in the new viewport.

If you are compiling Unreal from source you could change the engine code to just use your personal layout in the main window instead, using the game UGameViewport. This would move most of the effort from creating into debugging, but might save quite some time. Check UGameEngine::GameViewportWidget and where it is used.

I am still experimenting and facing some issues, so there might be problems I have not highlighted and steps I have not considered. But I would say that this is a fairly good starting point. I will update with more info once I am finished with that.

I cannot share any code unfortunately :pensive:

1 Like

A little update on my latest comment:

Unfortunately it is not suited for every use case, but creating a new window allows you to completely control its layout. This is by far the easiest way of having a viewport which does not take up all of the window. Plus you can use the Unreal Dock system to achieve customizable and movable layout similar to the one of Unreal Editor for free.
Something like this:

TSharedRef<SWindow> Window = SNew(SWindow)
	.Title(FText::FromString("Test"))
	.ScreenPosition({ 0.f, 0.f })
	.ClientSize({ 1920.f, 1080.f })
	.UseOSWindowBorder(true)
	.bDragAnywhere(true)
	.CreateTitleBar(true);

FSlateApplication::Get().AddWindow(Window);

// Tick now to force a redraw of the window and ensure correct fullscreen application
FSlateApplication::Get().Tick();
Window->BringToFront(true);
Window->SetContent(CreateContent());

with CreateContent()

const TSharedRef<FTabManager::FLayout> DefaultLayout = FTabManager::NewLayout("TestLayout")
->AddArea
(
	FTabManager::NewPrimaryArea() ->SetOrientation(Orient_Horizontal)
	->Split
	(
		FTabManager::NewStack()
		->AddTabTab("MyTab", ETabState::OpenedTab)
	)
);

TabManager->RegisterTabSpawner("MyTab", FOnSpawnTab::CreateLambda([](const FSpawnTabArgs&)
		{
            // Insert here code to create a new SViewport and setup ViewportClient.
			return SNew(SDockTab)[NewViewport];
		}));

TSharedPtr<SDockTab> DockTab = SNew(SDockTab)
	.TabRole(ETabRole::MajorTab)
	.ContentPadding(FMargin(0));
TSharedPtr<FTabManager> TabManager = FGlobalTabmanager::Get()->NewTabManager(DockTab.ToSharedRef());
return TabManager->RestoreFrom(DefaultLayout, Window.Pin()).ToSharedRef();

There are a bunch of part missing for making everything work, but this should give you a good starting point. I promise that at some point I will write a more detailed guide. However the Unreal Editor code is the best way to understand how to do this kind of things =). You can use some of the method I have written above to check for references in the code.

1 Like