Hello people, I’m trying to use the OnlineSubsystem just for the sake of learning and was trying to copy and learn some of the stuff used in the ShooterGame example. As of now I just want to show on screen the achievements, I set up steam with the steam test app (appId: 480) and can see the Steam overlay on the screen so I guess it’s working. Now, on my screen when I hit a button I create an object of an achievements class which is the responsible for showing the achievements. The thing is that when I click said button the game just crashes with a fatal error and not a single description of what could be the cause, however on the output logs I see the following
LogOnline:Warning: STEAM: Can't start an online game for session (Game) that hasn't been created
And thought it might be related so I decided to create a session on blueprints before instancing the achievements class and still no luck.
I managed to isolate the issue by commenting line by line until I hit the line of the problem which is where I get the Identity Interface, again, the game just crashes on that line so I don’t know what would be the cause.
Do I need to create a session just to see the achievements? if so, why is my logic not working.
Here’s my logic.
Here’s my achievements class definition:
#include "Object.h"
#include "OnlineSubsystem.h"
#include "OnlineAchievementsInterface.h"
#include "OnlineIdentityInterface.h"
#include "Achievements.generated.h"
/**
*
*/
UCLASS(BlueprintType)
class PROJECTMARIO_API UAchievements : public UObject
{
GENERATED_BODY()
private:
IOnlineSubsystem* SubsystemInstance;
IOnlineAchievementsPtr AchievementsInterface;
public:
UAchievements();
/**
* Called when the read achievements request from the server is complete
*
* @param PlayerId The player id who is responsible for this delegate being fired
* @param bWasSuccessful true if the server responded successfully to the request
*/
void OnQueryAchievementsComplete(const FUniqueNetId& PlayerId, const bool bWasSuccessful);
/**
* Reads achievements to precache them before first use
*/
void QueryAchievements();
void DummyShowAchievements(const bool bWasSuccessful);
UFUNCTION(BlueprintCallable, Category = "Online")
void ShowAchievements();
};
and the actual implementation:
#include "ProjectMario.h"
#include "Achievements.h"
UAchievements::UAchievements()
{
/*SubsystemInstance = IOnlineSubsystem::Get();
if (SubsystemInstance)
{
AchievementsInterface = SubsystemInstance->GetAchievementsInterface();
}*/
}
void UAchievements::QueryAchievements()
{
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(UGameplayStatics::GetPlayerController(GetWorld(), 0)->Player);
if (LocalPlayer && LocalPlayer->GetControllerId() != -1)
{
/** Making sure we got the onlinesubsystem **/
if (!SubsystemInstance)
{
SubsystemInstance = IOnlineSubsystem::Get();
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "No online sub");
}
if (SubsystemInstance)
{
/** Make sure we got the player **/
IOnlineIdentityPtr Identity = SubsystemInstance->GetIdentityInterface();
if (Identity.IsValid())
{
/** Make sure the player controller actually exists **/
TSharedPtr<const FUniqueNetId> UserId = Identity->GetUniquePlayerId(LocalPlayer->GetControllerId());
if (UserId.IsValid())
{
if (!AchievementsInterface.IsValid())
AchievementsInterface = SubsystemInstance->GetAchievementsInterface();
if (AchievementsInterface.IsValid())
{
AchievementsInterface->QueryAchievements(*UserId.Get(), FOnQueryAchievementsCompleteDelegate::CreateUObject(this, &UAchievements::OnQueryAchievementsComplete));
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Invalid achievements interface");
}
}
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Invalid Identity");
}
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "No online sub");
}
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Not Local player");
}
}
void UAchievements::OnQueryAchievementsComplete(const FUniqueNetId& PlayerId, const bool bWasSuccessful)
{
if (bWasSuccessful)
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Successful onquery");
DummyShowAchievements(bWasSuccessful);
}
else
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Not successful onquery");
}
/** DUMMY SHOW ACHIEVEMENTS**/
void UAchievements::DummyShowAchievements(const bool bWasSuccessful)
{
if (bWasSuccessful)
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "Sucess getting achievements \n");
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "List of Achievements are \n");
TArray<FOnlineAchievement> OutAchievements;
/** BOILERPLATE FOR GETTING CACHED ACHIEVEMENTS !!!!!!!!! **/
/**
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
**/
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(UGameplayStatics::GetPlayerController(GetWorld(), 0)->Player);
if (LocalPlayer && LocalPlayer->GetControllerId() != -1)
{
/** Making sure we got the onlinesubsystem **/
if (!SubsystemInstance)
SubsystemInstance = IOnlineSubsystem::Get();
if (SubsystemInstance)
{
/** Make sure we got the player **/
IOnlineIdentityPtr Identity = SubsystemInstance->GetIdentityInterface();
if (Identity.IsValid())
{
/** Make sure the player controller actually exists **/
TSharedPtr<const FUniqueNetId> UserId = Identity->GetUniquePlayerId(LocalPlayer->GetControllerId());
if (UserId.IsValid())
{
if (!AchievementsInterface.IsValid())
AchievementsInterface = SubsystemInstance->GetAchievementsInterface();
if (AchievementsInterface.IsValid())
{
AchievementsInterface->GetCachedAchievements(*UserId.Get(), OutAchievements);
}
}
}
}
}
for (FOnlineAchievement& Achievement : OutAchievements)
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, Achievement.ToDebugString());
}
}
else
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, "debug msg");
}
void UAchievements::ShowAchievements()
{
QueryAchievements();
}
I’m also attaching the logs:
[here][2]