首页 > 解决方案 > 无法在 Unity 中使用 Steamworks.NET 获取或设置成就

问题描述

我正在使用 Steamworks.NET 在我正在开发的游戏中设置 Steam 成就。SteamManager 初始化正确,App ID 设置正确,成就已发布。但是,调用 GetAchievement 会返回 false。SetAchievement 有同样的问题,并且永远不会调用 UserAchievementStored_t 回调。对 Steamworks API 的所有其他调用都返回 true,并且它们的回调被触发且没有错误。

任何关于为什么这些调用返回错误或任何其他要检查的想法都将不胜感激。


这是我的代码:

public class SteamAchievementManager : AchievementManager
{
    List<AchievementID> achievementQueue = new List<AchievementID>();
    List<AchievementID> backupAchievementQueue = new List<AchievementID>();

    private Callback<UserStatsReceived_t> statsRequestedResult;
    private Callback<UserStatsStored_t> statsStoredResult;
    private Callback<UserAchievementStored_t > achievementStoredResult;

    bool awarding = false;

    int retryCount = 0;
    int maxRetryCounts = 5;

    public override void Init()
    {
        if( !SteamManager.Initialized )
        {
            Debug.LogError( "Tried to Init SteamAchievementManager but SteamManager is not initialised" );
            return;
        }

        //Steamworks.SteamUserStats.ResetAllStats( true );

        statsRequestedResult = Callback<UserStatsReceived_t>.Create( OnStatsReceived );
        statsStoredResult = Callback<UserStatsStored_t>.Create( OnStatsStored );
        achievementStoredResult = Callback<UserAchievementStored_t>.Create( OnAchievementStored );

        SteamUserStats.RequestCurrentStats();
    }

    public override void AwardAchievement( AchievementID achievementID )
    {
        if( !SteamManager.Initialized )
        {
            Debug.LogError( "Tried to Award Achievement but SteamManager is not initialised" );
            return;
        }

        achievementQueue.Add( achievementID );
        if( !awarding )
            AttemptToAwardAndStoreAchievements();
    }

    void AttemptToAwardAndStoreAchievements()
    {
        awarding = true;

        if( SteamUserStats.RequestCurrentStats() )
        {
            Debug.Log( "Successfully Requested Stats" );
        }
        else
        {
            Debug.LogError( "Failed to Request Stats" );
            CompleteAwarding( false );
        }
    }

    void OnStatsReceived( UserStatsReceived_t result )
    {
        if( result.m_eResult != EResult.k_EResultFail )
        {
            Debug.Log( "Successfully Received Stats " + result.m_eResult );
            AwardQueuedAchievements();
        }
        else
        {
            Debug.LogError( "Failed To Received Stats" );
            CompleteAwarding( false );
        }
    }

    void AwardQueuedAchievements()
    {
        List<AchievementID> achievementsToAward = new List<AchievementID>( achievementQueue );

        while( achievementQueue.Count > 0 )
        {
            AchievementID achievementID = achievementQueue[ achievementQueue.Count - 1 ];
            string steamID = AchievementData.achievementList.GetAchievement( achievementID ).steamID;
            bool alreadyAwarded;
            Debug.Log( Steamworks.SteamUserStats.GetAchievementDisplayAttribute( steamID, "name" ) );
            if( !Steamworks.SteamUserStats.GetAchievement( steamID, out alreadyAwarded ) )
            {
                Debug.LogError( "Failed To Get Achievement: " + steamID );
            }
            if( !alreadyAwarded )
            {
                if( Steamworks.SteamUserStats.SetAchievement( steamID ) )
                {
                    Debug.Log( "Awarded Achievement: " + steamID );
                }
                else
                {
                    Debug.LogError( "Failed To Awarded Achievement: " + steamID );
                    backupAchievementQueue.Add( achievementID );
                }
            }
            achievementQueue.RemoveAt( achievementQueue.Count - 1 );
        }

        SetStats();
    }

    private void OnAchievementStored( UserAchievementStored_t result )
    {
        Debug.Log( "Achievement Stored Callback" );
    }

    public void SetStats()
    {
        SteamUserStats.StoreStats();
    }

    private void OnStatsStored( UserStatsStored_t result )
    {
        if( result.m_eResult != EResult.k_EResultFail )
            Debug.Log( "Achievement Stats Succesfully Stored" );
        else
            Debug.LogError( "Achievement Stats Failed To Store" );

        CompleteAwarding( result.m_eResult != EResult.k_EResultFail && backupAchievementQueue.Count == 0 );
    }

    void CompleteAwarding( bool wasSuccesful )
    {
        awarding = false;
        retryCount = wasSuccesful ? 0 : retryCount + 1;
        achievementQueue.AddRange( backupAchievementQueue );
        backupAchievementQueue.Clear();

        if( retryCount > maxRetryCounts )
        {
            Debug.LogError( "Failed to Award Achievements After Multiple Attempts" );
            retryCount = 0;
        }
        else if( achievementQueue.Count > 0 )
        {
            retryCount++;
            AttemptToAwardAndStoreAchievements();
        }
    }
}

标签: unity3dsteamachievementssteamworks-api

解决方案


原来应用 ID 是错误的(通过在 OnStatsStored 中打印 result.m_nGameID 来解决这个问题)。我确信我有正确的 ID,因为当我导入包时,在 Steamworks 插件文件夹中创建了一个 steam_appid.txt 文件,我已将其更改为具有正确的 ID。然而,在项目根文件夹中还有另一个 steam_appid.txt 文件,这是从中提取 id 的地方,而这个仍然有错误的 id。

所以基本上我是在我崩溃之前先疱疹。现在都在工作!


推荐阅读