UE4 如何在程序运行时多开窗口和解锁鼠标
窗口多开
说明
多开窗口涉及 SWindow 的窗口类。
在该窗口类中可以添加内容,然后再把该窗口添加到程序实例中。
实例
demo如下所示:
- 新建c++空工程
- 添加一个c++ actor类(我这里叫MultiWindowsActor)
- 编写一个调用函数
//.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include <Runtime/UMG/Public/Blueprint/UserWidget.h>
#include "Runtime/Engine/Public/Slate/SceneViewport.h"
#include "Runtime/SlateCore/Public/Widgets/SWindow.h"
#include "Runtime/Slate/Public/Widgets/SViewport.h"
#include "Runtime/SlateCore/Public/Widgets/SOverlay.h"
#include "Runtime/Slate/Public/Framework/Application/SlateApplication.h"
#include "Runtime/Slate/Public/Widgets/Layout/SConstraintCanvas.h"
#include "MultiWindowsActor.generated.h"
UCLASS()
class MULTIWINDOW_API AMultiWindowsActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMultiWindowsActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintCallable, Category = "MutilWindows")
void CreateSpectatorWindow(FVector2D WindowSize, FVector2D WindowPosition, UUserWidget * showWidget, bool autoCenter);
TSharedPtr<SWindow> SpectatorWindow = nullptr;
EWindowMode::Type WindowMode;
void DestroySpectatorWindow();
bool bIsStandaloneGame = false;
};
//.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MultiWindowsActor.h"
// Sets default values
AMultiWindowsActor::AMultiWindowsActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AMultiWindowsActor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMultiWindowsActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMultiWindowsActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
DestroySpectatorWindow();
}
void AMultiWindowsActor::CreateSpectatorWindow(FVector2D WindowSize, FVector2D WindowPosition, UUserWidget * showWidget, bool autoCenter)
{
//WindowMode = EWindowMode::WindowedFullscreen;
// Create and add window
SpectatorWindow = SNew(SWindow)
.ScreenPosition(WindowPosition)
.ClientSize(WindowSize)
.SizingRule(ESizingRule::UserSized)
.Title(FText::FromString(TEXT("Custom SpectatorWindow")))
.AutoCenter(autoCenter?(EAutoCenter::PrimaryWorkArea):(EAutoCenter::None))
.FocusWhenFirstShown(false)
.UseOSWindowBorder(true)
.UserResizeBorder(true)
.CreateTitleBar(true)
.SupportsTransparency(EWindowTransparency::PerWindow)
.InitialOpacity(1.0f)
.SupportsMaximize(true);
SpectatorWindow->SetViewportSizeDrivenByWindow(true);
//获取当前应用的实例
FSlateApplication & SlateApp = FSlateApplication::Get();
//添加新建的窗口到该实例中
SlateApp.AddWindow(SpectatorWindow.ToSharedRef(), true);
//新建一个内容画布
TSharedRef<SConstraintCanvas> ViewportWidget = SNew(SConstraintCanvas);
TSharedPtr<SWidget> SlateWidget = showWidget->TakeWidget();
// Add slate widget to window
ViewportWidget->AddSlot()
[
//放置添加内容的位置
SlateWidget.ToSharedRef()
]
;
ViewportWidget->SetVisibility(EVisibility::Visible);
//内容设置
SpectatorWindow->SetContent(ViewportWidget);
SpectatorWindow->ShowWindow();
//设置窗口模式
SpectatorWindow->SetWindowMode(EWindowMode::Windowed);
bIsStandaloneGame = GetWorld()->WorldType == EWorldType::Game;
}
void AMultiWindowsActor::DestroySpectatorWindow()
{
// Destroy window
if (SpectatorWindow.Get() != nullptr)
{
if (bIsStandaloneGame == false)
{
SpectatorWindow->RequestDestroyWindow();
}
else
{
SpectatorWindow->DestroyWindowImmediately();
}
}
}
编译然后打开项目文件
新建actor继承上面的actor,然后再begin中调用,把新建的actor拖入场景中。启动项目
(在这里建一个widget做测试,该widget只有一个按钮,点击之后打印)
自己编写了一个插件插件
小插件