Массив возвращает плохие значения только в первый раз

Так что я работаю со Steamworks (списки лидеров), и у меня возникла странная проблема. Когда я запускаю свою функцию, чтобы получить оценки, из отладки я знаю, что она работает просто отлично. Однако мой массив после 1-го запуска функции всегда возвращает значения по умолчанию. После того, как я запускаю функцию во второй раз, все работает отлично. Я попытался отследить проблему, однако мне не удалось.

Вот весь мой код, который я использую в этом случае:

Структура для статистики

 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;

};

Функция, которая отправила запрос в Steam:
.час

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:
.час

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;}
}

И, наконец, функция, которая записывает оценки в массиве:

.час

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 Scores and scores = true предназначен только для скрытой проверки с функциями после вызова DownloadScoresAroundUser 🙂

Мой нормальный поток с этим:
1.У меня уже есть ручка для списка лидеров.
2. Я звоню DownloadScoresAroundUser.
3. Поток идет в латентный режим, который не может продолжаться, потому что счет = ложь.
4.После того как я получил ответный звонок от Steam OnDownloadScore, он дал мне всю необходимую информацию (проверено, действительно ли так и есть!).
5. Затем я вызываю TranslateEntries, чтобы получить все результаты с именами и рейтингом в массиве.
6. Затем я печатаю весь массив (с разрывом пакета в нереальном) и получаю значения по умолчанию для моей структуры.
7. После того, как я снова запускаю весь цикл, я получаю правильные значения.

Если потребуется дополнительная информация, дайте мне знать 🙂

0

Решение

Это немного предположение, но, похоже, у вас есть проблема с задержкой. Когда вы делаете запрос на загрузку результатов, это занимает много времени и не блокируется. Вы настраиваете обратный вызов, который будет вызываться, когда счет будет готов, а затем возвращать существующий пустой Scores объект.

Когда вы делаете второй звонок, прошло достаточно времени для загрузки и оценки Scores быть заполненным, поэтому он возвращает несколько баллов.

Обратите внимание, что у вас есть потенциальное состояние гонки, где DownloadScoresAroundUser может получить доступ (возврат) Scores в то время как ваш обратный вызов заполняет этот вектор.

Вот одно из возможных решений. До того, как результаты завершены, DownloadScoresAroundUser возвращает пустой счет (или, возможно, тот, который указывает, что результаты загружаются). После того, как результаты были загружены и Scores населенный, он вернет тех. Кроме того, обратный вызов (помимо заполнения Scores) может каким-либо образом уведомить вызывающего абонента о DownloadScoresAndUser что новые оценки доступны. Они могут ответить на этот вопрос, позвонив снова, чтобы получить обновленные оценки и обновить дисплей.

1

Другие решения

Переводчики копируют данные от 0 до 30, но только «Callback-> m_cEntryCount» фактически инициализируются. Так что если это < на 30 данные от «Callback-> m_cEntryCount» до 30 могут быть неверными. Можете ли вы распечатать значение этой переменной «в SteamLeaderboard :: OnDownloadScore»?

0

По вопросам рекламы [email protected]