这一次到了p19
完善了UI和写了创建房间
MultiPlayerSessionSubsystem.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Subsystems/GameInstanceSubsystem.h" #include "Interfaces/OnlineSessionInterface.h" #include "MultiPlayerSessionSubsystem.generated.h" /** * */ UCLASS() class UMultiPlayerSessionSubsystem : public UGameInstanceSubsystem { GENERATED_BODY() public: UMultiPlayerSessionSubsystem(); /* * 这里是一个句柄,让菜单类可以访问Subsystem */ void CreateSession(int32 NumPublicConnections,FString MatchType); void FindSession(int32 MaxSearchResults); void JoinSession(const FOnlineSessionSearchResult& SessionResults); void DestroySession(); void StartSession(); protected: /* * 这里是委托 */ void CreateSessionComplete(FName SessionName, bool bWasSuccessful); void FindSessionsComplete(bool bWasSuccessful); void JoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result); void DestroySessionComplete(FName SessionName, bool bWasSuccessful); void StartSessionComplete(FName SessionName, bool bWasSuccessful); private: IOnlineSessionPtr OnlineSessionInterface; TSharedPtr
MultiPlayerSessionSubsystem.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "MultiPlayerSessionSubsystem.h" #include "OnlineSessionSettings.h" #include "OnlineSubsystem.h" UMultiPlayerSessionSubsystem::UMultiPlayerSessionSubsystem(): CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this,&ThisClass::CreateSessionComplete)), FindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this,&ThisClass::FindSessionsComplete)), JoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this,&ThisClass::JoinSessionComplete)), DestroySessionCompleteDelegate(FOnDestroySessionCompleteDelegate::CreateUObject(this,&ThisClass::DestroySessionComplete)), StartSessionCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this,&ThisClass::StartSessionComplete)) { IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get(); if(OnlineSubsystem) { OnlineSessionInterface = OnlineSubsystem->GetSessionInterface(); } } void UMultiPlayerSessionSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType) { if(!OnlineSessionInterface.IsValid()) { return; } auto ExistingSession = OnlineSessionInterface->GetNamedSession(NAME_GameSession); if(ExistingSession != nullptr) { OnlineSessionInterface->DestroySession(NAME_GameSession); } //存放创建委托 CreateSessionCompleteDelegate_Handle = OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate); LastSessionSettings = MakeShareable(new FOnlineSessionSettings()); LastSessionSettings->bIsLANMatch = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true:false; //最多4人 LastSessionSettings->NumPublicConnections =NumPublicConnections; //允许其他玩家加入 LastSessionSettings->bAllowJoinInProgress = true; //允许好友加入 LastSessionSettings->bAllowJoinViaPresence = true; //线上公开 LastSessionSettings->bShouldAdvertise = true; //显示用户状态 LastSessionSettings->bUsesPresence = true; //使用第三方 LastSessionSettings->bUseLobbiesIfAvailable = true; LastSessionSettings->Set(FName("MatchType"),MatchType,EOnlineDataAdvertisementType::ViaOnlineServiceAndPing); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); if(OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession , *LastSessionSettings)) { OnlineSessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate_Handle); } } void UMultiPlayerSessionSubsystem::FindSession(int32 MaxSearchResults) { } void UMultiPlayerSessionSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResults) { } void UMultiPlayerSessionSubsystem::DestroySession() { } void UMultiPlayerSessionSubsystem::StartSession() { } void UMultiPlayerSessionSubsystem::CreateSessionComplete(FName SessionName, bool bWasSuccessful) { } void UMultiPlayerSessionSubsystem::FindSessionsComplete(bool bWasSuccessful) { } void UMultiPlayerSessionSubsystem::JoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result) { } void UMultiPlayerSessionSubsystem::DestroySessionComplete(FName SessionName, bool bWasSuccessful) { } void UMultiPlayerSessionSubsystem::StartSessionComplete(FName SessionName, bool bWasSuccessful) { }
BaseMenu.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "BaseMenu.generated.h" /** * */ class UButton; UCLASS() class MULTIPLAYERSESSION_API UBaseMenu : public UUserWidget { GENERATED_BODY() protected: virtual bool Initialize() override; virtual void NativeDestruct(); public: UFUNCTION(BlueprintCallable) void MenuSetup(int SetupNumPublicConnections = 4,FString SetupMatchType = TEXT("FreeForAll")); void _DebugLog(FColor DisplayColor, const FString& DebugMessage); private: //将指针与按钮绑定起来,这里的绑定必须要指针变量名称和UMG的名称完全一样 UPROPERTY(meta=(BindWidget)) UButton* HostButton; UPROPERTY(meta=(BindWidget)) UButton* JoinButton; UFUNCTION() void HostButtonClicked(); UFUNCTION() void JoinButtonClincked(); UFUNCTION() void MenuTearDown(); class UMultiPlayerSessionSubsystem* MultiPlayerSessionSubsystem; int32 NumPublicConnections{4}; FString MatchType{TEXT("FreeForAll")}; };
BaseMenu.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "BaseMenu.h" #include "MultiPlayerSession/Public/MultiPlayerSessionSubsystem.h" #include "Components/Button.h" bool UBaseMenu::Initialize() { if(!Super::Initialize()) { return false; } if(HostButton) { HostButton->OnClicked.AddDynamic(this,&UBaseMenu::HostButtonClicked); } if(JoinButton) { JoinButton->OnClicked.AddDynamic(this,&UBaseMenu::JoinButtonClincked); } return true; } void UBaseMenu::MenuSetup(int SetupNumPublicConnections ,FString SetupMatchType) { NumPublicConnections = SetupNumPublicConnections; MatchType = SetupMatchType; AddToViewport(); SetVisibility(ESlateVisibility::Visible); bIsFocusable = true; UWorld* World = GetWorld(); if(World) { APlayerController* PlayerController = World->GetFirstPlayerController(); if(PlayerController) { FInputModeUIOnly InputModeUIOnly; InputModeUIOnly.SetWidgetToFocus(TakeWidget()); InputModeUIOnly.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); PlayerController->SetInputMode(InputModeUIOnly); PlayerController->SetShowMouseCursor(true); } } UGameInstance* GameInstance = GetGameInstance(); if(GameInstance) { MultiPlayerSessionSubsystem = GameInstance->GetSubsystem