1、将steamworks.Net导入项目
(1)steamworks.NET下载
2、修改游戏id
找到 steam_appid.txt 打开;将480替换为你游戏申请的ID;
3、编写“成就”脚本
using UnityEngine;
using Steamworks;
/// <summary>
/// Steam成就
/// </summary>
public class SteamAchievements : MonoBehaviour
{
/// <summary>
/// 成就单例
/// </summary>
public static SteamAchievements Instance {
get; private set; } = null;
// kill the number
private int _killNumber = 0;
public int KillNumber {
get {
return _killNumber; }
set {
_killNumber = value;
SteamUserStats.SetStat("KillEnemyAmount", _killNumber);
}
}
// Our GameID
private CGameID m_GameID;
// Did we get the stats from Steam?
private bool m_bRequestedStats;
private bool m_bStatsValid;
// Should we store stats this frame?
private bool m_bStoreStats;
// achievements call-back
private Callback<UserStatsReceived_t> m_UserStatsReceived;
private Callback<UserStatsStored_t> m_UserStatsStored;
private Callback<UserAchievementStored_t> m_UserAchievementStored;
// all achievements in the game
private Achievement_t[] m_Achievements = new Achievement_t[] {
new Achievement_t(Achievement.ACH_FIRST_BLOOD, "ACH_FIRST_BLOOD", ""),
// ......
};
private void OnEnable()
{
if (!SteamManager.Initialized)
return;
// Cache the GameID for use in the Callbacks
m_GameID = new CGameID(SteamUtils.GetAppID());
m_UserStatsReceived = Callback<UserStatsReceived_t>.Create(OnUserStatsReceived);
m_UserStatsStored = Callback<UserStatsStored_t>.Create(OnUserStatsStored);
m_UserAchievementStored = Callback<UserAchievementStored_t>.Create(OnAchievementStored);
// These need to be reset to get the stats upon an Assembly reload in the Editor.
m_bRequestedStats = false;
m_bStatsValid = false;
Instance = this;
}
private void Update()
{
if (!SteamManager.Initialized)
return;
if (!m_bRequestedStats)
{
// Is Steam Loaded? if no, can't get stats, done
if (!SteamManager.Initialized)
{
m_bRequestedStats = true;
return;
}
// If yes, request our stats
bool bSuccess = SteamUserStats.RequestCurrentStats();
// This function should only return false if we weren't logged in, and we already checked that.
// But handle it being false again anyway, just ask again later.
m_bRequestedStats = bSuccess;
}
if (!m_bStatsValid)
return;
// Refreshing achievement data
UpdateCurAchievements();
// Store stats in the Steam database if necessary
if (m_bStoreStats)
{
// already set any achievements in UnlockAchievement
// set stats
SteamUserStats.SetStat("KillEnemyAmount", KillNumber);
bool bSuccess = SteamUserStats.StoreStats();
// If this failed, we never sent anything to the server, try again later.
m_bStoreStats = !bSuccess;
}
}
//-----------------------------------------------------------------------------
// Purpose: Refreshing achievement data
//-----------------------------------------------------------------------------
private void UpdateCurAchievements()
{
// get achievement progress
if (Input.GetKeyDown(KeyCode.Space))
{
LoadStats();
}
// Reset achievement statistics
else if (Input.GetKeyDown(KeyCode.Escape))
{
SteamUserStats.ResetAllStats(true);
SteamUserStats.RequestCurrentStats();
}
// test: achievement progress add
else if (Input.GetKeyDown(KeyCode.F1))
{
++KillNumber;
}
// Evaluate achievements
foreach (Achievement_t achievement in m_Achievements)
{
// achievement been activated, skip;
if (achievement.m_bAchieved)
continue;
// is can unlock achievement
switch (achievement.m_eAchievementID)
{
case Achievement.ACH_FIRST_BLOOD:
if (KillNumber >= 1)
{
UnlockAchievement(achievement);
}
break;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Unlock this achievement
//-----------------------------------------------------------------------------
private void UnlockAchievement(Achievement_t achievement)
{
achievement.m_bAchieved = true;
// the icon may change once it's unlocked
//achievement.m_iIconImage = 0;
// mark it down
SteamUserStats.SetAchievement(achievement.m_eAchievementID.ToString());
// Store stats end of frame
m_bStoreStats = true;
}
//-----------------------------------------------------------------------------
// Purpose: We have stats data from Steam. It is authoritative, so update
// our data with those results now.
//-----------------------------------------------------------------------------
private void OnUserStatsReceived(UserStatsReceived_t pCallback)
{
if (!SteamManager.Initialized)
return;
// we may get callbacks for other games' stats arriving, ignore them
if ((ulong)m_GameID == pCallback.m_nGameID)
{
if (EResult.k_EResultOK == pCallback.m_eResult)
{
Debug.Log("Received stats and achievements from Steam\n");
m_bStatsValid = true;
// load achievements
foreach (Achievement_t ach in m_Achievements)
{
bool ret = SteamUserStats.GetAchievement(ach.m_eAchievementID.ToString(), out ach.m_bAchieved);
if (ret)
{
ach.m_strName = SteamUserStats.GetAchievementDisplayAttribute(ach.m_eAchievementID.ToString(), "name");
ach.m_strDescription = SteamUserStats.GetAchievementDisplayAttribute(ach.m_eAchievementID.ToString(), "desc");
}
else
{
Debug.LogWarning("SteamUserStats.GetAchievement failed for Achievement " + ach.m_eAchievementID + "\nIs it registered in the Steam Partner site?");
}
}
// load stats
LoadStats();
}
else
{
Debug.Log("RequestStats - failed, " + pCallback.m_eResult);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Our stats data was stored!
//-----------------------------------------------------------------------------
private void OnUserStatsStored(UserStatsStored_t pCallback)
{
// we may get callbacks for other games' stats arriving, ignore them
if ((ulong)m_GameID == pCallback.m_nGameID)
{
if (EResult.k_EResultOK == pCallback.m_eResult)
{
Debug.Log("StoreStats - success");
}
else if (EResult.k_EResultInvalidParam == pCallback.m_eResult)
{
// One or more stats we set broke a constraint. They've been reverted,
// and we should re-iterate the values now to keep in sync.
Debug.Log("StoreStats - some failed to validate");
// Fake up a callback here so that we re-load the values.
UserStatsReceived_t callback = new UserStatsReceived_t();
callback.m_eResult = EResult.k_EResultOK;
callback.m_nGameID = (ulong)m_GameID;
OnUserStatsReceived(callback);
}
else
{
Debug.Log("StoreStats - failed, " + pCallback.m_eResult);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: An achievement was stored
//-----------------------------------------------------------------------------
private void OnAchievementStored(UserAchievementStored_t pCallback)
{
// We may get callbacks for other games' stats arriving, ignore them
if ((ulong)m_GameID == pCallback.m_nGameID)
{
if (0 == pCallback.m_nMaxProgress)
{
Debug.Log("Achievement '" + pCallback.m_rgchAchievementName + "' unlocked!");
}
else
{
Debug.Log("Achievement '" + pCallback.m_rgchAchievementName + "' progress callback, (" + pCallback.m_nCurProgress + "," + pCallback.m_nMaxProgress + ")");
}
}
}
//-----------------------------------------------------------------------------
// Purpose: load stats
//-----------------------------------------------------------------------------
private void LoadStats()
{
int number = 0;
SteamUserStats.GetStat("TotalGamesPlayed", out number);
KillNumber = number;
}
/// <summary>
/// Achievement instance
/// </summary>
private class Achievement_t
{
public Achievement m_eAchievementID;
public string m_strName;
public string m_strDescription;
public bool m_bAchieved;
/// <summary>
/// Creates an Achievement. You must also mirror the data provided here in https://partner.steamgames.com/apps/achievements/yourappid
/// </summary>
/// <param name="achievement">The "API Name Progress Stat" used to uniquely identify the achievement.</param>
/// <param name="name">The "Display Name" that will be shown to players in game and on the Steam Community.</param>
/// <param name="desc">The "Description" that will be shown to players in game and on the Steam Community.</param>
public Achievement_t(Achievement achievementID, string name, string desc)
{
m_eAchievementID = achievementID;
m_strName = name;
m_strDescription = desc;
m_bAchieved = false;
}
}
/// <summary>
/// all the achievements of our game
/// </summary>
private enum Achievement : int
{
/// <summary>
/// 完成第1次击杀
/// </summary>
ACH_FIRST_BLOOD,
// ......
};
// //-----------------------------------------------------------------------------
// // Purpose: Display the user's stats and achievements
// //-----------------------------------------------------------------------------
// public void Render() {
// if (!SteamManager.Initialized) {
// GUILayout.Label("Steamworks not Initialized");
// return;
// }
//
// //GUILayout.Label("m_ulTickCountGameStart: " + m_ulTickCountGameStart);
// //GUILayout.Label("m_flGameDurationSeconds: " + m_flGameDurationSeconds);
// //GUILayout.Label("m_flGameFeetTraveled: " + m_flGameFeetTraveled);
// //GUILayout.Space(10);
// GUILayout.Label("TotalGamesPlayed: " + m_nTotalGamesPlayed);
// GUILayout.Label("TotalNewBiesPlayed: " + m_nTotalNewBiesPlayed);
// GUILayout.Label("TotalEnemiesKilled: " + m_nTotalEnemiesKilled);
// GUILayout.Label("TotalFullBloodPassEasy: " + m_nTotalFullBloodPassEasy);
// GUILayout.Label("TotalFullBloodPassHard: " + m_nTotalFullBloodPassHard);
// GUILayout.Label("TotalGamePassEasy: " + m_nTotalGamePassEasy);
// GUILayout.Label("TotalGamePassHard: " + m_nTotalGamePassHard);
// GUILayout.Label("TotalFishKilled: " + m_nTotalFishKilled);
// GUILayout.Label("TotalExplosionShoot: " + m_nTotalExplosionShoot);
//
// GUILayout.BeginArea(new Rect(Screen.width - 300, 0, 300, 800));
// //foreach(Achievement_t ach in m_Achievements) {
// //一页显示10个
// for (int i = m_nPageIndex * 10; i < m_Achievements.Length && i < (m_nPageIndex * 10 + 10); ++i)
// {
// Achievement_t ach = m_Achievements[i];
// GUILayout.Label(ach.m_eAchievementID.ToString());
// //GUILayout.Label(ach.m_strName + " - " + ach.m_strDescription);
// GUILayout.Label("Achieved: " + ach.m_bAchieved);
// GUILayout.Space(5);
// }
//
// // FOR TESTING PURPOSES ONLY!
// if (GUILayout.Button("RESET STATS AND ACHIEVEMENTS")) {
// SteamUserStats.ResetAllStats(true);
// SteamUserStats.RequestCurrentStats();
// }
// GUILayout.EndArea();
// }
//
}
4、完成;可根据F1、Space、Esc等按键测试是否接入成功
5、你需要去steam上配置游戏的成就,就ok了。