UE通过SWindow创建多窗口体验,通过RenderTarget在独立窗口中呈现场景画面

实现的效果是UE运行后,有两个独立窗口,一个是蓝图创建添加到视口的(MainUI,带场景),一个是C++New 的SWindow(SecondUI,这种方式创建的窗口不能直接加载场景,但是可以用RenderTarget将主场景的画面渲染过来), 运行效果如下图:

一、c++创建新的窗口(这里用的是一个Actor类)

  •  模块引用,在 .Build.cs中添加模块 "SlateCore", "Slate", "UMG" 
  •  头文件引用

#include "Blueprint/UserWidget.h"
#include "Widgets/SWindow.h"
#include "Kismet/GameplayStatics.h"
#include "Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h"

  •  创建SWindow

   NewWindowTemp = SNew(SWindow)
        .AutoCenter(EAutoCenter::PrimaryWorkArea)
        .ClientSize(ClientSize)
        .SizingRule(ESizingRule::UserSized)
        .CreateTitleBar(true)
        .FocusWhenFirstShown(false)
        .UseOSWindowBorder(true)
        .UserResizeBorder(true)
        .CreateTitleBar(true)
        .SupportsTransparency(EWindowTransparency::PerWindow)
        .InitialOpacity(1.0f)
        .SupportsMaximize(true);

TSharedRef<SWindow> NewWindow = NewWindowTemp.ToSharedRef();

注意 .ClientSize(FVector2D (1920,1080))的传值 

  •  我是UMG写的widget,所以需要t转SWidget(也可以直接用slate写),如果页面逻辑都是在蓝图Widget里面写的,可以把SecondWindowWidget暴露给蓝图,蓝图可以直接拿这个变量使用,做窗口之间的通讯。

.h

UPROPERTY(EditAnywhere, BlueprintReadOnly)
UUserWidget* SecondWindowWidget = nullptr; 

.cpp

UClass* WidgetClass = LoadClass<UUserWidget>(NULL, TEXT("/Game/UI/Widget_SecondUI.Widget_SecondUI_C"));
    UUserWidget* UserWidget = nullptr;
    TSharedPtr <SWidget> SlateWidget;
    if (WidgetClass && GWorld->GetWorld())
    {
        UserWidget = CreateWidget<UUserWidget>(GWorld->GetWorld(), WidgetClass);
        SecondWindowWidget = UserWidget;
    }
    if (UserWidget)
    {
        SlateWidget = UserWidget->TakeWidget();
    }

这里要特别注意蓝图widget的名称格式是:name.name_C ("名称"+“.”+"名称"+“_C”),否则为空

 不确定路径格式的可以鼠标悬浮在widget上,会有它的路径 

  •  窗口中添加内容并显示窗口

NewWindow->SetViewportSizeDrivenByWindow(true);
        FSlateApplication::Get().AddWindow(NewWindow, true);
        NewWindow->SetContent(SlateWidget.ToSharedRef());
        NewWindow->ShowWindow();
        NewWindow->SetWindowMode(EWindowMode::Windowed);

        NewWindow->SetOnWindowClosed(FOnWindowClosed::CreateLambda([=](const TSharedRef<SWindow>& WindowArg)
            {
                APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0);
                UKismetSystemLibrary::QuitGame(this, PlayerController, EQuitPreference::Quit, true);
            }));        

二、在新建的窗口中 用RenderTarget反射主场景的画面

  • 创建一个RenderTarget 

设置RenderTarget纹理的分辨率

  •  创建一个Material,并编辑材质

将RenderTarget纹理作为输入连接到相应的节点或属性上

  •  创建蓝图Actor,使用SceneCaptureComponent2D组件设置RenderTarget为捕捉组件的渲染目标,以实现实时反射或屏幕空间效果

  •  将Actor放在场景中,调整要看到画面的视角

  • 通过获取RenderTarget的引用,可以对其进行绘制、更新或擦除操作。这里是在蓝图中使用DrawMaterialToRenderTarget节点,将一个材质绘制到RenderTarget上。

实现效果就是第一张图

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值