所以我正在使用Steamworks(排行榜),我有一些奇怪的问题。当我启动我的功能获得分数时,从调试我知道它工作得很好。但是我的数组在第一次运行后运行总是返回默认值。在我第二次触发功能后,一切都运行得很好。我试图追查这个问题但是我失败了。
以下是我在这种情况下使用的完整代码:
统计数据的结构
USTRUCT(BlueprintType)
struct FScorePackage
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Leaderboard")
FString PlayerName = "working";
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Leaderboard")
int32 Rank = 0;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Leaderboard")
int32 Score = 0;
};
向蒸汽发送请求的功能: .H
UFUNCTION(BlueprintCallable, Category = "Steam|Leaderboard", meta = (Latent, LatentInfo = "LatentInfo", HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
TArray<FScorePackage> DownloadScoresAroundUser(UObject* WorldContextObject, int AboveUser, int BelowUser, struct FLatentActionInfo LatentInfo);
的.cpp
TArray<FScorePackage> USteamLeaderboard::DownloadScoresAroundUser(UObject* WorldContextObject, int AboveUser, int BelowUser, struct FLatentActionInfo LatentInfo)
{
if (!m_CurrentLeaderboard)
{
return Scores;
}
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject))
{
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
if (LatentActionManager.FindExistingAction<SteamLeaderboardLatentClass>(LatentInfo.CallbackTarget, LatentInfo.UUID) == NULL)
{
// load the specified leaderboard data around the current user
SteamAPICall_t hSteamAPICall = SteamUserStats()->DownloadLeaderboardEntries(m_CurrentLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -AboveUser, BelowUser);
m_callResultDownloadScore.Set(hSteamAPICall, this,&USteamLeaderboard::OnDownloadScore);
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new SteamLeaderboardLatentClassScores(LatentInfo));
return Scores;
}
return Scores;
}
return Scores;
}
现在来自steam的回调函数: .H
void OnDownloadScore(LeaderboardScoresDownloaded_t *pResult, bool bIOFailure);
CCallResult <USteamLeaderboard, LeaderboardScoresDownloaded_t> m_callResultDownloadScore;
的.cpp
void USteamLeaderboard::OnDownloadScore(LeaderboardScoresDownloaded_t *pCallback, bool bIOFailure)
{
if (!bIOFailure)
{
m_nLeaderboardEntries = __min(pCallback->m_cEntryCount, 30);
for (int index = 0; index < m_nLeaderboardEntries; index++)
{
SteamUserStats()->GetDownloadedLeaderboardEntry(pCallback->m_hSteamLeaderboardEntries, index, &m_leaderboardEntries[index], NULL, 0);
}
TranslateEntries();
scores = true;
}
}
最后在Array中编写分数的函数:
·H
UFUNCTION(BlueprintCosmetic, Category = "Steam|Leaderboard")
TArray<FScorePackage> TranslateEntries();
的.cpp
TArray<FScorePackage> USteamLeaderboard::TranslateEntries()
{
FScorePackage ThisScore;
Scores.Init(ThisScore, 30);
for (int i = 0; i < 30; i++)
{
ThisScore.PlayerName = GetSteamName(m_leaderboardEntries[i].m_steamIDUser);
ThisScore.Rank = m_leaderboardEntries[i].m_nGlobalRank;
ThisScore.Score = m_leaderboardEntries[i].m_nScore;
Arrayas[i] = ThisScore;
}
return Scores;
}
Scores数组只是静态TArray分数,score = true仅用于在调用DownloadScoresAroundUser后进行潜在检查以继续使用函数:)
我的正常流程是: 我已经掌握了排行榜。 我正在调用DownloadScoresAroundUser。 3.Flow进入潜伏状态,因为得分=假而无法进行。 4.在我收到来自Steam OnDownloadScore的回调后,给我所有需要的信息(检查是否确实如此!)。 然后我调用TranslateEntries获取所有在数组中名称和等级的分数。 然后我打印整个数组(使用unreal中的break包)并获取我的struct的默认值。 在我再次开启整个循环后,我得到了适当的价值。
如果需要任何进一步的信息,请告诉我:)
答案 0 :(得分:1)
这是一个猜测,但看起来你有一个延迟问题。当您提出下载分数的请求时,这是一个不会阻止的耗时调用。您设置了一个回调,该回调将在分数准备就绪时调用,然后返回现有的空Scores
对象。
当您进行第二次通话时,已经有足够的时间让分数下载并填充Scores
,因此会返回一些分数。
请注意,您有一个潜在的竞争条件,DownloadScoresAroundUser
可以在您的回调填充该向量时访问(返回)Scores
。
这是一个可能的解决方案。在分数加载完成之前,DownloadScoresAroundUser
会返回一个空分数(或者可能是一个表示正在加载分数的分数)。加载分数并填充Scores
后,它将返回这些分数。此外,回调(除了填充Scores
)可以以某种方式通知DownloadScoresAndUser
的呼叫者新分数可用。他们可以通过再次呼叫来获取更新的分数并刷新显示来响应。
答案 1 :(得分:0)
Translateentries将数据从0复制到30,但实际上只初始化了“Callback-&gt; m_cEntryCount”。所以如果它&lt;在30处,从“Callback-&gt; m_cEntryCount”到30的数据可能是错误的。你能在“SteamLeaderboard :: OnDownloadScore”中打印出这个变量的值吗?