UE5切换关卡函数OpenLevel,输入模式结构体,UI界面
1.输入模式结构体
FInputModeGameOnly
:玩家只能与游戏世界交互,UI 不可交互。FInputModeGameAndUI
:玩家可以与游戏世界和 UI 同时交互。FInputModeUIOnly
:玩家只能与 UI 交互,无法与游戏世界进行互动。
FInputModeGameOnly:
构造函数,默认设置输入模式为仅游戏输入模式,鼠标光标会隐藏,所有输入都会被传递到游戏。没有额外的设置函数,FInputModeGameOnly
只会设置输入为游戏模式,不需要额外的配置。
FInputModeGameAndUI:
构造函数,默认设置输入模式为游戏和 UI 模式。在此模式下,玩家可以同时与游戏和 UI 交互。
FInputModeUIOnly:构造函数,默认设置输入模式为仅 UI 输入模式。在此模式下,玩家只能与 UI 进行交互,游戏输入会被禁用
函数SetWidgetToFocus(TSharedPtr<SWidget> InWidgetToFocus) 参数是某个UI界面的指针,作用是将只关注这个InWidgetToFocus界面
函数SetLockMouseToViewportBehavior(EMouseLockMode InMouseLockMode)设置鼠标模式,EMouseLockMode这个枚举中有注释
这两个函数可能只会在FInputModeGameAndUI,和
FInputModeUIOnly使用。
2.OpenLevel函数,切换关卡
#include "Kismet/GameplayStatics.h"
UGameplayStatics::OpenLevel(
const UObject* WorldContextObject, // 一般是UWorld指针,或者是APlayerController指针。UWorld指针可以通过GetWorld()函数获得 , APlayerController看你在哪个类中,查询具体的获得方式,一般是UWorld
FName LevelName, //切换到哪个关卡的名字
bool bAbsolute = true, //是否是绝对路径 ,一般是默认值,第二个参数给地图的名字即可
FString Options = FString(TEXT("")) // 不知到是干什么用的,
)
3.UI界面
1.创建自UserWidget的子类,(UE中还有一个HUD也是于UI相关的类,我的理解是如果想显示角色的血量,子弹数等比较小的UI使用HUD,如果是游戏初始界面使用UserWidget)
2.类中代码 , MenuSetup函数设置为蓝图可以调用的函数,使用AddToViewport显示UI界面,设置FInputModeUIOnly,我在点击按钮后设置了游戏模式函数是Button0Printf,在Initilize函数中绑定,Button0是按钮的名字,要和UE中的UI编辑器中的名字一样,SetGameModel函数中设置FInputModeGameOnly InputModeData;SetInputMode(InputModeData);两行。在是地图的关卡蓝图中调用menuSetup函数,中间的界面是create widget选择Class需要创建这个UI类的蓝图类,在切换关卡后如果角色不可以操作可以查看
输入模式结构体有没有重新设置成FInputModeGameOnly或者FInputModeGameAndUI
class JUMP_API UStartUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void MenuSetup();
protected:
virtual bool Initialize() override;
public:
UPROPERTY(meta = (BindWidget))
UButton* Button0;
private:
UFUNCTION()
void Button0Printf();
};
void UStartUserWidget::MenuSetup()
{
AddToViewport();
SetVisibility(ESlateVisibility::Visible);/* 设置可见性 */
bIsFocusable = true;/* 设置聚焦模式 */
UWorld* World = GetWorld();
if (World)
{
APlayerController* PlayerController = World->GetFirstPlayerController();
if (PlayerController)
{
FInputModeUIOnly InputModeData;
InputModeData.SetWidgetToFocus(TakeWidget());/* 设置只关注与小部件 */
InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);/* 设置鼠标光标锁定 */
PlayerController->SetInputMode(InputModeData);//设置模式集中于界面
PlayerController->SetShowMouseCursor(true);/* 看到光标 */
}
}
}
bool UStartUserWidget::Initialize()
{
if (!Super::Initialize())
{
return false;
}
if (Button0)
{
Button0->OnClicked.AddDynamic(this, &UStartUserWidget::Button0Printf);//绑定回调函数
}
return true;
}
void UStartUserWidget::Button0Printf()
{
UWorld* World = GetWorld();
if (World)
{
UGameplayStatics::OpenLevel(World, FName(TEXT("JumpMap")));
AJumpCharacterController* PlayerController = Cast<AJumpCharacterController>(World->GetFirstPlayerController());
if (PlayerController)
{
PlayerController->SetGameModel();
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("World pointer is nullptr"));
}
}
4.关于UE中父类容器的概念
父类容器的概念通常是指 一个类或对象包含并管理其他对象或数据的结构,比如UWorld中管理这很多AActor。使用GetOuter()函数可以返回当前类的父类容器,父类容器绝对不是当前类的父类。