using Steamworks; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class AchievementSystem : MonoBehaviour { //part of the unlocks menu. Controls tracking and unlocking of achievements within the achievements list //track different events that occur within the game and then unlock achievements once thresholds are met. //Save any changes to values or achievement unlocks so they persist between sessions. //12 ints, 4 bools, 2 floats private int deathWallDeaths; //death wall sends info private int bouncyWallUses; //wall sends info private bool gotNearDeathWall; //death wall sends info private bool diedByNormalObstacle; //to determine if the player did not die by the death wall private int stickyWallUses; //wall sends info private int slipperyWallUses; //wall sends info private int maxSessionScore; //score manager sends info when max score changes private int timesScoreAboveOneHundred; //score manager sends info when score goes over 100 private int itemsPickedUp; //item sends info private int totalInvulnTime; //item sends info private bool allUnlocksGot; //unlocks manager sends info when last unlock is got private bool allColorDropsGot; //unlocks system sends info when all color drop unlocks are opened private float totalPlayTime; //this class tracks the play time private int timesDiedToObstacles; //obstacle sends info private int timesSwitchedPaths; //a trigger volume on tiles that have an opening will send info private float timeSpentInStartZone;//this class will track the time spent in the start zone. Time will stop tracking when the score managers score goes over 10. private int maxScoreMultiplier; //score manager will send info when the multiplier changes private int maxSpeedBoost; // score manager will send info when boost changes private bool secretUnlocked; //tracks if the player made it to the secret area private bool[] achievementsGot = new bool[21]; //tracks if an achievement has been unlocked public GameObject achievementsParent; public List<Sprite> unlockedImages = new List<Sprite>(); private List<GameObject> achievementObjects = new List<GameObject>(); private List<GameObject> checkMarks = new List<GameObject>(); private List<TextMeshProUGUI> progressTexts = new List<TextMeshProUGUI>(); private List<Image> achievementImages = new List<Image>(); private SoundManager soundMgr; private ScoreManager scoreMgr; private bool chillModeActive; private void Awake() { foreach (RectTransform item in achievementsParent.GetComponentsInChildren<RectTransform>()) { if (item.name.Contains("Achievement")) achievementObjects.Add(item.gameObject); if (item.name.Contains("Image")) achievementImages.Add(item.GetComponent<Image>()); if (item.name == "Check Mark") checkMarks.Add(item.gameObject); if (item.name == "Progress Display") progressTexts.Add(item.GetComponent<TextMeshProUGUI>()); } soundMgr = GetComponent<SoundManager>(); scoreMgr = GetComponent<ScoreManager>(); } private void Start() { if (!SteamManager.Initialized) { return; } SteamUserStats.RequestCurrentStats(); } private void Update() { if (!chillModeActive) { if (!GUIManager.GetMainMenuCanvasState()) totalPlayTime += Time.deltaTime; if (scoreMgr.GetCurrentScore() < 10 && !GUIManager.GetMainMenuCanvasState()) timeSpentInStartZone += Time.deltaTime; CheckForUnlocks(); } } public void SetChillModeActiveState(bool state) { //when chill mode is on, no achievements will progress. chillModeActive = state; } public bool GetChillModeActiveState() { return chillModeActive; } public void OnRunReset() { diedByNormalObstacle = false; gotNearDeathWall = false; } public void ResetAchievements() { deathWallDeaths = 0; bouncyWallUses = 0; stickyWallUses = 0; slipperyWallUses = 0; maxSessionScore = 0; timesScoreAboveOneHundred = 0; itemsPickedUp = 0; totalInvulnTime = 0; timesDiedToObstacles = 0; timesSwitchedPaths = 0; maxScoreMultiplier = 0; maxSpeedBoost = 0; progressTexts[0].text = deathWallDeaths + "/" + 100; progressTexts[1].text = bouncyWallUses + "/" + 100; progressTexts[3].text = bouncyWallUses + "/" + 100; progressTexts[4].text = bouncyWallUses + "/" + 100; progressTexts[5].text = maxSessionScore + "/" + 1000; progressTexts[6].text = maxSessionScore + "/" + 2000; progressTexts[7].text = timesScoreAboveOneHundred + "/" + 25; progressTexts[8].text = itemsPickedUp + "/" + 100; progressTexts[9].text = totalInvulnTime + "/" + 100; progressTexts[15].text = timesDiedToObstacles + "/" + 100; progressTexts[16].text = timesSwitchedPaths + "/" + 10; progressTexts[18].text = maxScoreMultiplier + "/" + 10; progressTexts[19].text = maxSpeedBoost + "/" + 140; allUnlocksGot = false; allColorDropsGot = false; secretUnlocked = false; totalPlayTime = 0; timeSpentInStartZone = 0; for (int i = 0; i < achievementsGot.Length; i++) { achievementsGot[i] = false; checkMarks[i].GetComponent<Image>().enabled = false; } SaveManager.DeleteAchievementInfo(); if (!SteamManager.Initialized) { return; } SteamUserStats.ResetAllStats(false); } public void SetSavedInformation(int[] savedInts, bool[] savedBools, float[] savedFloats, bool[] savedUnlockStates) { deathWallDeaths = savedInts[0]; progressTexts[0].text = deathWallDeaths + "/" + 100; bouncyWallUses = savedInts[1]; progressTexts[1].text = bouncyWallUses + "/" + 100; stickyWallUses = savedInts[2]; progressTexts[3].text = bouncyWallUses + "/" + 100; slipperyWallUses = savedInts[3]; progressTexts[4].text = bouncyWallUses + "/" + 100; maxSessionScore = savedInts[4]; progressTexts[5].text = maxSessionScore + "/" + 1000; progressTexts[6].text = maxSessionScore + "/" + 2000; timesScoreAboveOneHundred = savedInts[5]; progressTexts[7].text = timesScoreAboveOneHundred + "/" + 25; itemsPickedUp = savedInts[6]; progressTexts[8].text = itemsPickedUp + "/" + 100; totalInvulnTime = savedInts[7]; progressTexts[9].text = totalInvulnTime + "/" + 100; timesDiedToObstacles = savedInts[8]; progressTexts[15].text = timesDiedToObstacles + "/" + 100; timesSwitchedPaths = savedInts[9]; progressTexts[16].text = timesSwitchedPaths + "/" + 10; maxScoreMultiplier = savedInts[10]; progressTexts[18].text = maxScoreMultiplier + "/" + 10; maxSpeedBoost = savedInts[11]; progressTexts[19].text = maxSpeedBoost + "/" + 140; allUnlocksGot = savedBools[0]; allColorDropsGot = savedBools[1]; secretUnlocked = savedBools[2]; totalPlayTime = savedFloats[0]; timeSpentInStartZone = savedFloats[1]; for (int i = 0; i < savedUnlockStates.Length; i++) { if (savedUnlockStates[i]) { checkMarks[i].GetComponent<Image>().enabled = true; achievementImages[i].sprite = unlockedImages[i]; } } if (!SteamManager.Initialized) { return; } SteamUserStats.SetStat("Death_Wall_Deaths", deathWallDeaths); SteamUserStats.SetStat("Bouncy_Wall_Uses", bouncyWallUses); SteamUserStats.SetStat("Sticky_Wall_Uses", stickyWallUses); SteamUserStats.SetStat("Slippery_Wall_Uses", slipperyWallUses); SteamUserStats.SetStat("Max_Session_Score", maxSessionScore); SteamUserStats.SetStat("Times_Score_Above_One_Hundred", timesScoreAboveOneHundred); SteamUserStats.SetStat("Items_Picked_Up", itemsPickedUp); SteamUserStats.SetStat("Total_Invuln_Time", totalInvulnTime); int allUnlocksInt = 0; int allColorDropsInt = 0; int secretUnlockedInt = 0; int diedToDeathWall = 0; if (allUnlocksGot == true) allUnlocksInt = 1; if (allColorDropsGot == true) allColorDropsInt = 1; if (secretUnlocked == true) secretUnlockedInt = 1; if (achievementsGot[2] == true) diedToDeathWall = 1; SteamUserStats.SetStat("All_Unlocks_Got", allUnlocksInt); SteamUserStats.SetStat("All_Color_Drops_Got", allColorDropsInt); SteamUserStats.SetStat("Secret_Unlocked", secretUnlockedInt); SteamUserStats.SetStat("To_The_Edge_Got", diedToDeathWall); SteamUserStats.SetStat("Total_Play_Time", totalPlayTime); SteamUserStats.SetStat("Times_Died_To_Obstacles", timesDiedToObstacles); SteamUserStats.SetStat("Times_Switched_Paths", timesSwitchedPaths); SteamUserStats.SetStat("Time_Spent_In_Start_Zone", timeSpentInStartZone); SteamUserStats.SetStat("Max_Score_Multiplier", maxScoreMultiplier); SteamUserStats.SetStat("Max_Speed_Boost", maxSpeedBoost); SteamUserStats.StoreStats(); } public void SaveAchievementValues() { int[] savedInts = new int[12]; bool[] savedBools = new bool[3]; float[] savedFloats = new float[2]; savedInts[0] = deathWallDeaths; savedInts[1] = bouncyWallUses; savedInts[2] = stickyWallUses; savedInts[3] = slipperyWallUses; savedInts[4] = maxSessionScore; savedInts[5] = timesScoreAboveOneHundred; savedInts[6] = itemsPickedUp; savedInts[7] = totalInvulnTime; savedInts[8] = timesDiedToObstacles; savedInts[9] = timesSwitchedPaths; savedInts[10] = maxScoreMultiplier; savedInts[11] = maxSpeedBoost; savedBools[0] = allUnlocksGot; savedBools[1] = allColorDropsGot; savedBools[2] = secretUnlocked; savedFloats[0] = totalPlayTime; savedFloats[1] = timeSpentInStartZone; //send info to save manager SaveManager.SaveAchievementSystemInfo(savedInts, savedBools, savedFloats, achievementsGot); if (!SteamManager.Initialized) { return; } SteamUserStats.SetStat("Death_Wall_Deaths", deathWallDeaths); SteamUserStats.SetStat("Bouncy_Wall_Uses", bouncyWallUses); SteamUserStats.SetStat("Sticky_Wall_Uses", stickyWallUses); SteamUserStats.SetStat("Slippery_Wall_Uses", slipperyWallUses); SteamUserStats.SetStat("Max_Session_Score", maxSessionScore); SteamUserStats.SetStat("Times_Score_Above_One_Hundred", timesScoreAboveOneHundred); SteamUserStats.SetStat("Items_Picked_Up", itemsPickedUp); SteamUserStats.SetStat("Total_Invuln_Time", totalInvulnTime); int allUnlocksInt = 0; int allColorDropsInt = 0; int secretUnlockedInt = 0; int diedToDeathWall = 0; if (allUnlocksGot == true) allUnlocksInt = 1; if (allColorDropsGot == true) allColorDropsInt = 1; if (secretUnlocked == true) secretUnlockedInt = 1; if (achievementsGot[2] == true) diedToDeathWall = 1; SteamUserStats.SetStat("All_Unlocks_Got", allUnlocksInt); SteamUserStats.SetStat("All_Color_Drops_Got", allColorDropsInt); SteamUserStats.SetStat("Secret_Unlocked", secretUnlockedInt); SteamUserStats.SetStat("To_The_Edge_Got", diedToDeathWall); SteamUserStats.SetStat("Total_Play_Time", totalPlayTime); SteamUserStats.SetStat("Times_Died_To_Obstacles", timesDiedToObstacles); SteamUserStats.SetStat("Times_Switched_Paths", timesSwitchedPaths); SteamUserStats.SetStat("Time_Spent_In_Start_Zone", timeSpentInStartZone); SteamUserStats.SetStat("Max_Score_Multiplier", maxScoreMultiplier); SteamUserStats.SetStat("Max_Speed_Boost", maxSpeedBoost); } public void CheckForUnlocks() { //check all values to see if any can be unlocked if (deathWallDeaths >= 100) UnlockAchievement(0); if (bouncyWallUses >= 100) UnlockAchievement(1); if (gotNearDeathWall && diedByNormalObstacle) UnlockAchievement(2); if (stickyWallUses >= 100) UnlockAchievement(3); if (slipperyWallUses >= 100) UnlockAchievement(4); if (maxSessionScore > 1000) UnlockAchievement(5); if (maxSessionScore > 2000) UnlockAchievement(6); if (timesScoreAboveOneHundred > 25) UnlockAchievement(7); if (itemsPickedUp > 100) UnlockAchievement(8); if (totalInvulnTime > 100) UnlockAchievement(9); if (allUnlocksGot) UnlockAchievement(10); if (allColorDropsGot) UnlockAchievement(11); if (totalPlayTime > 600) UnlockAchievement(12); if (totalPlayTime > 1800) UnlockAchievement(13); if (totalPlayTime > 3200) UnlockAchievement(14); if (timesDiedToObstacles >= 100) UnlockAchievement(15); if (timesSwitchedPaths > 10) UnlockAchievement(16); if (timeSpentInStartZone > 300) UnlockAchievement(17); if (maxScoreMultiplier >= 10) UnlockAchievement(18); if (maxSpeedBoost >= 140) UnlockAchievement(19); if (secretUnlocked) UnlockAchievement(20); } public void UnlockAchievement(int achID) { if (!achievementsGot[achID]) { Image checkImage = checkMarks[achID].GetComponent<Image>(); bool checkState = checkImage.enabled; if (!checkState) { checkImage.enabled = true; soundMgr.PlayNotificationPing(); achievementImages[achID].sprite = unlockedImages[achID]; string achievementTitle = ""; foreach (RectTransform item in achievementObjects[achID].GetComponentsInChildren<RectTransform>()) { if (item.name == "Header") { achievementTitle = item.GetComponent<TextMeshProUGUI>().text; break; } } GUIManager.SetAchText(achievementTitle); GUIManager.PlayAchievementAnim(); if (!SteamManager.Initialized) { return; } string apiTitle = achievementTitle; apiTitle = apiTitle.Replace(' ', '_'); SteamUserStats.SetAchievement(apiTitle); SteamUserStats.StoreStats(); } switch (achID) { case 10: soundMgr.AddMusicToLibrary("Imagine"); break; case 14: soundMgr.AddMusicToLibrary("Flora (Alt.)"); break; case 6: soundMgr.AddMusicToLibrary("Cascade"); break; case 20: soundMgr.AddMusicToLibrary("Artificial Serenity (Piano)"); break; } achievementsGot[achID] = true; } } public void IncrementDeathWallDeaths() { if (!chillModeActive) { deathWallDeaths++; SaveAchievementValues(); progressTexts[0].text = deathWallDeaths + "/" + 100; } } public void IncrementBouncyWallUses() { if (!chillModeActive) { bouncyWallUses++; SaveAchievementValues(); progressTexts[1].text = bouncyWallUses + "/" + 100; } } public void SetNearDeathWall(bool state) { if (!chillModeActive) { gotNearDeathWall = state; SaveAchievementValues(); } } public void SetDeathByObstacle(bool state) { if (!chillModeActive) { diedByNormalObstacle = state; SaveAchievementValues(); } } public void IncrementStickyWallUses() { if (!chillModeActive) { stickyWallUses++; SaveAchievementValues(); progressTexts[3].text = stickyWallUses + "/" + 100; } } public void IncrementSlipperyWallUses() { if (!chillModeActive) { slipperyWallUses++; SaveAchievementValues(); progressTexts[4].text = slipperyWallUses + "/" + 100; } } public void SetMaxScore(int newMaxScore) { if (!chillModeActive) { maxSessionScore = newMaxScore; SaveAchievementValues(); progressTexts[5].text = maxSessionScore + "/" + 1000; progressTexts[6].text = maxSessionScore + "/" + 2000; } } public void IncrementScoreAboveOneHundred() { if (!chillModeActive) { timesScoreAboveOneHundred++; SaveAchievementValues(); progressTexts[7].text = timesScoreAboveOneHundred + "/" + 25; } } public void IncrementItemsPickedUp() { if (!chillModeActive) { itemsPickedUp++; SaveAchievementValues(); progressTexts[8].text = itemsPickedUp + "/" + 100; } } public void IncrementInvulnTime(int invulnTime) { if (!chillModeActive) { totalInvulnTime += invulnTime; SaveAchievementValues(); progressTexts[9].text = totalInvulnTime + "/" + 100; } } public void SetAllUnlocksGot(bool state) { if (!chillModeActive) { allUnlocksGot = state; SaveAchievementValues(); } } public void SetAllColorDropsGot(bool state) { if (!chillModeActive) { allColorDropsGot = state; SaveAchievementValues(); } } public void IncrementTimesDiedToObstacles() { if (!chillModeActive) { timesDiedToObstacles++; SaveAchievementValues(); progressTexts[15].text = timesDiedToObstacles + "/" + 100; } } public void IncrementTimesSwitchedPaths() { if (!chillModeActive) { timesSwitchedPaths++; SaveAchievementValues(); progressTexts[16].text = timesSwitchedPaths + "/" + 10; } } public void SetMaxScoreMultiplier(int newMax) { if (!chillModeActive) { maxScoreMultiplier = newMax; SaveAchievementValues(); progressTexts[18].text = maxScoreMultiplier + "/" + 10; } } public void SetMaxSpeedBoost(int newMax) { if (!chillModeActive) { maxSpeedBoost = newMax; SaveAchievementValues(); progressTexts[19].text = maxSpeedBoost + "/" + 140; } } public void SetSecretUnlocked(bool state) { if (!chillModeActive) { secretUnlocked = state; SaveAchievementValues(); } } }