OnlineSubsystem Steam 연결 및 Create Session
OnlineSubsystem Steam에 연결해보자
먼저 언리얼 공식 문서에 검색해보면 다음의 구문을 Config/Engine.ini 파일에 추가하라고 되어있다.
[/Script/Engine.GameEngine]
+NetDriverDefinitions=(DefName="GameNetDriver",DriverClassName="OnlineSubsystemSteam.SteamNetDriver",DriverClassNameFallback="OnlineSubsystemUtils.IpNetDriver")
[OnlineSubsystem]
DefaultPlatformService=Steam
[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=480
; If using Sessions
; bInitServerOnClient=true
[/Script/OnlineSubsystemSteam.SteamNetDriver]
NetConnectionClassName="OnlineSubsystemSteam.SteamNetConnection"
중간에 세션을 사용할거면 bInitServerOnClient=true 문장을 추가하라고 되있다.
아마 세션 멀티플레이 기능을 사용하지 않고 도전과제, 친구 등의 기능만 사용하는 개발자들을 위해 저부분을 주석처리 한것 같다.
우리는 세션 기능을 사용할것이기 때문에 주석을 풀어준다.
그리고 uproject 파일을 우클릭해 Generate project file을 해준다.
다음으로 할일은 Character 클래스에 세션 로직을 추가해 Steam에 실제로 연결이 되는지 확인하는 것이다.
1인칭 기본 템플릿으로 프로젝트를 생성한다.
plugin을 열어 OnlineSubsystem Steam을 체크해주면 에디터를 재시작하라고 뜨는데 순순히 따라준다.
이러면 플러그인은 추가됬고, 코드로 가서 로직을 작성해보자.
캐릭터 클래스에 세션 관리 로직을 추가한다.
멀티플레이 게임이기 때문에 각각의 유저가 세션 생성, 세션 참가 등의 활동을 수행할것이다.
따라서 캐릭터 클래스에 로직을 추가해야 각각의 플레이어가 문제없이 세션 관련 활동을 진행할 수 있을것이다.
캐릭터의 생성자에 OnlineSubsystem을 Get 함수로 받아오고 헤더파일에 선언한 OlnineSessionInterface 변수에 SessionInterface를 저장해준다.
// MenuCharacter.h
public:
// Pointer to the online session Interface
IOnlineSessionPtr OnlineSessionInterface;
// MenuCharacter.cpp
// Session Section
IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get();
if (OnlineSubsystem) {
OnlineSessionInterface = OnlineSubsystem->GetSessionInterface();
}
이러고 빌드를 하면 에러가 뜬다.
키워드는 C3646
IOnlineSessionPtr 타입의 변수로 선언한 OnlineSessionInterface가 unknown override specifier라는 에러이다.
보통 포인터 변수를 선언할 때 전방선언을 해준다. 하지만 IOnline session pointer 타입으로 선언한 OnlineSessionInterface 변수는 그렇게 할 수 없는데, 변수가 ESPMode의 thread safe으로 지정된 SharedPtr 변수이며 Thread Safe를 보장받는 스마트 포인터이기 때문이다.
두가지 해결방법이 있는데, 하나는 헤더에 OnlineSubsystem을 추가하는 것이고 다른 하나는 TSharedPtr로 스마트포인터를 감싸는것이다.
이번엔 후자의 방법을 간단히 사용하겠다.
public:
// Pointer to the online session Interface
TSharedPtr<class IOnlineSession, ESPMode::ThreadSafe> OnlineSessionInterface;
이렇게 해서 PIE로 테스트 해보면, 전부 Subsystem Null이 잡힌다.
Subsystem NULL은 NULL값이 아니라, 플랫폼이 NULL인것.
패키징해서 실행해보면 Steam 연결이 잘 되는걸 확인할 수 있다.
Delegates
- 언리얼 엔진의 함수 reference를 가지고 있는 오브젝트
- 함수를 바인딩해 시그널을 broadcasting시켜 각 함수가 실행되도록 하는 역할
- 콜백 함수를 델리게이트에 바인딩 한다.
- 게임에서 특정 이벤트가 일어나면 델리게이트는 fire되거나 broadcast를 실행하고 그 응답으로 콜백 함수가 실행된다.
- 온라인 세션 인터페이스는 델리게이트들을 이용하는데, 세션을 생성하거나 참가하는걸 인터넷을 통해 정보를 수신받아야 할 수 있기 때문. 인터넷 속도에 따라 시간이 소요되는것도 당연

CreateSession
- 헤더에 CreateSession함수, 델리게이트, 콜백함수를 선언해준다.
UPROPERTY(BlueprintCallable)
void CreateGameSession();
void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);
private:
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
- 그리고 cpp파일의 캐릭터 생성자에 델리게이트를 바인딩한다.
- 생성자에 델리게이트 바인딩? -> 객체 생성 시점에 해당 이벤트를 처리할 준비를 마치기 위해.
- 기본 구조: FDelegateType::CreateUObject(UObjectInstance, &ClassName::FunctionName);
- CreateUObject: 델리게이트에 현재 객체와 멤버함수를 바인딩, UObjectInstance: 델리게이트를 호출할 때 사용할 UObjectInstance, &ClassName::FunctionName: 호출할 함수의 포인터.
AMenuCharacter::AMenuCharacter():
CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &AMenuCharacter::OnCreateSessionComplete))
- 그리고 가장 먼저 할 일은, 세션이 이미 있는지 확인 후 없애는것.
- 이후 세션 세팅을 설정해주고, CreateSession으로 세션 생성을 마친다.
void AMenuCharacter::CreateGameSession()
{
// Called when pressing the 1 key
if (!OnlineSessionInterface.IsValid()) {
return;
}
auto ExistingSession = OnlineSessionInterface->GetNamedSession(NAME_GameSession);
if (ExistingSession != nullptr) {
OnlineSessionInterface->DestroySession(NAME_GameSession);
}
OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate);
TSharedPtr<FOnlineSessionSettings> SessionSettings = MakeShareable(new FOnlineSessionSettings());
SessionSettings->bIsLANMatch = false;
SessionSettings->NumPublicConnections = 4;
SessionSettings->bAllowJoinInProgress = true;
SessionSettings->bAllowJoinViaPresence = true;
SessionSettings->bShouldAdvertise = true;
SessionSettings->bUsesPresence = true;
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *SessionSettings);
}
void AMenuCharacter::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("Faild to Create Session!"))
);
}
}
}
- 그다음 window 버전으로 패키징 후 실행시켜보면, 스팀 오버레이가 우하단에 출력되며 올바르게 연결된것을 확인할 수 있다.
'개발 일지' 카테고리의 다른 글
플러그인 등록 (0) | 2024.11.30 |
---|---|
Join Session (0) | 2024.11.29 |
Listen Server와 Dedicated Server (0) | 2024.11.26 |
계속되는 세션 오류 (0) | 2024.11.22 |
세션 관리 이동 (0) | 2024.11.20 |