언리얼5

[UE5 Multiplayer Shooting-3] UE 멀티 플레이어 플러그인 생성 01

TIN9 2023. 7. 25.
반응형

Online Subsystem Steam

스팀을 활용하기 위한 플러그인 활성화를 해준다.

활성화 후 프로젝트 재붙

기본적인 스팀 세션 동작 순서는 아래와 같다

Server
ClICK HOST ->(Session Settings) CREATE SESSION -> OPEN LOBBY

Client
CLICK JOIN ->(Search Settings) FIND SESSIONS -> (Pick a Valid Session) JOIN SESSION ->(Get the address) CLIENT TRAVEL

 

MenuSystem.build.cs

 OnlineSubSystem관련된 플러그인 내용을 사용하기 위해서는 "OnlineSubsystemSteam", "OnlineSubsystem"를 추가해줘야 한다.

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay",
		"OnlineSubsystemSteam", "OnlineSubsystem"});

 

DefaultEngine.ini

프로젝트 폴더 / Config / DefaultEngine.ini에 아래의 내용을 추가

아래의 내용을 ini에 추가해야 스팀을 온라인 서브시스템으로 사용할 수 있다.

[/Script/Engine.GameEngine]
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")

[OnlineSubsystem]
DefaultPlatformService=Steam

[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=480
bInitServerOnClient=true

[/Script/OnlineSubsystemSteam.SteamNetDriver]
NetConnectionClassName="OnlineSubsystemSteam.SteamNetConnection"

위의 내용을 추가했으면 프로젝트 폴더에서 Binaries, Saved, Intermedicate 폴더를 삭제 후 Generate Visual studio Project files를 클릭한 뒤 프로젝트 실행 후 아래의 코드들 작성

 

멤버 변수 및 멤버 함수(AMenuSystemCharacter.h)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "MenuSystemCharacter.generated.h"

UCLASS(config=Game)
class AMenuSystemCharacter : public ACharacter
{
	GENERATED_BODY()

	...
    
public:
	//  온라인 세션 인터페이스 포인터
	IOnlineSessionPtr m_OnlineSessionInterface;

protected:
	UFUNCTION(BlueprintCallable)
	void CreateGameSession();

	void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);

private:
	FOnCreateSessionCompleteDelegate m_CreateSessionCompleteDelegate;
};

 

Online Subsystem Access

Online Subsystem 인터페이스는 네트워킹 서비스에 대한 일반적인 인터페이스를 제공하며, 어떤 특정 플랫폼(Steam, Xbox Live, PlayStation Network 등)을 사용하더라도 동일한 코드를 사용할 수 있게 해 줍니다.

OnlineSubsystem 인스턴스로부터 세션 인터페이스를 얻어 사용

AMenuSystemCharacter::AMenuSystemCharacter()
{
	...
    
	IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get();

	// 유효한지 체크
	if (OnlineSubsystem)
	{
		m_OnlineSessionInterface = OnlineSubsystem->GetSessionInterface();

		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Blue,
				FString::Printf(TEXT("Found subsystem %s"),
				*OnlineSubsystem->GetSubsystemName().ToString()));
		}
	}
}

 

CreateGameSession

서버가 될 클라이언트가 다른 클라에서 접속이 가능하도록 세션을 생성

여기서 세션 정보를 입력한다(몇 명이 입장 가능한지와 같은 부분)

void AMenuSystemCharacter::CreateGameSession()
{
	// Called when pressing the 1 key
	if (!m_OnlineSessionInterface.IsValid())
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(
				-1,
				15.f,
				FColor::Red,
				FString(TEXT("OnlineSessionInterface not Valid"))
			);
		}
		return;
	}

	//NAME_GameSession을 사용하면 이 이름을 가진 세션이 존재하는지 항상 확인할 수 있다.
	auto ExistingSession = m_OnlineSessionInterface->GetNamedSession(NAME_GameSession);

	// 널이 아니라면 이미 있다는것이기 때문에 세션을 제거한다.
	if (ExistingSession != nullptr)
	{
		m_OnlineSessionInterface->DestroySession(NAME_GameSession);
	}

	// 온라인세션 인터페이스의 델리게이트 리스트에 델리게이트 추가
	// 세션을 생성하고 나면 이 델리게이트에게 바인딩한 콜백 기능이 호출된다.(OnCreateSessionComplete() 함수)
	m_OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(m_CreateSessionCompleteDelegate);

	// 스마트 포인터를 초기화하는 방법
	//FOnlineSessionSettings 에는 세션 세팅을 위해 사용
	TSharedPtr<FOnlineSessionSettings> SessionSettings = MakeShareable(new FOnlineSessionSettings());
	// 인터넷으로 할것이기 때문에 랜매치 x
	SessionSettings->bIsLANMatch = false;
	// 게임 플레이어 총원
	SessionSettings->NumPublicConnections = 4;
	// 게임 세션 실행중이면 다른유저도 가입 가능한지
	SessionSettings->bAllowJoinInProgress = true;
	// 스팀이 게임 세션을 설정할 때 존재한다는 것?
	// 전 세계 모든 플레이어와의 연결이 아닌 지역이 있고 지역에서 발생하는 세션 검색하도록
	SessionSettings->bAllowJoinViaPresence = true;
	// 스팀이 세션을 광고해서 다른 유저들이 참여할 수 있다.
	SessionSettings->bShouldAdvertise = true;
	// 현재 지역에서 진행중인 세션을 찾는다
	SessionSettings->bUsesPresence = true;
	// 로컬 플레이어를 얻어와 넷ID를 얻을 수 있다.
	const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
	// 세션 생성
	m_OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *SessionSettings);
}

쉽게 말해 세션 인터페이스에 접근해 세션 함수 생성을 호출하면 정보가 스팀으로 전송되고
스팀에 게임 세션이 생성이 된다.

그러면 스팀이 기기로 정보를 다시 보내(callbackfunction()) 세션을 생성하는 작업이 완료됐음을 알리는 개념이다

 

CallbackFunc 등록

세션 인터페이스의 델리게이트 리스트에 저장할 델리게이트의 콜백 함수를 멤버 초기화 리스트를 사용하여 초기화를 진행

AMenuSystemCharacter::AMenuSystemCharacter()	:
	m_CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateSessionComplete))

CallbackFunc 구현 부분

우선 이번 포스팅에서는 세션이 생성됐는지 안 됐는지만을 확인하기 위해 디버깅용 메시지 함수를 적용

void AMenuSystemCharacter::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{
	if (bWasSuccessful)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(
				-1,
				15.f,
				FColor::Blue,
				FString::Printf(TEXT("Created session : %s"), *SessionName.ToString())
			);
		}
	}
	else
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(
				-1,
				15.f,
				FColor::Red,
				FString(TEXT("Failed to create session!"))
			);
		}
	}
}

결과

좌상단에 보이는 것처럼 서브스트림 스팀을 찾았고 키를 입력하여 게임 세션을 생성한 것을 확인할 수 있다.

반응형

댓글