Forum begins after the advertisement:
[Part 9] UI stats
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 9] UI stats
- This topic has 7 replies, 3 voices, and was last updated 1 week, 5 days ago by
Jukers.
-
AuthorPosts
-
March 18, 2025 at 7:02 am #17555::
i made it to the final part o the ui (around 35:40) of the part 9. but it didnt work, my text ui didnt change at any moment, i did everything correctly and revised a couple times i think theres something wrong in my script, but i cant seem to find it at first when i tested, it didnt work, i resumed the tutorial to see if it would fix when he changed, but still didnt work here’s my code PlayerStats.cs
using System.Collections.Generic; using UnityEngine; public class PlayerStats : MonoBehaviour { public CharacterScriptableObject characterData; //status atuais float currentHealth; float currentRecovery; float currentMoveSpeed; float currentMight; // basicamente dano float currentProjectileSpeed; float currentProjectileDuration; float currentMagnet; #region Current Stats Properties public float CurrentHealth { get { return currentHealth; } set { //checa se o valor mudou if(currentHealth != value) { currentHealth = value; if(GameManager.instance != null) { GameManager.instance.currentHealthDisplay.text = "Health: " + currentHealth; } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } public float CurrentRecovery { get { return currentRecovery; } set { //checa se o valor mudou if(currentRecovery != value) { currentRecovery = value; if(GameManager.instance !=null) { GameManager.instance.currentRecoveryDisplay.text = "Recovery: " + currentRecovery; } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } public float CurrentMoveSpeed { get { return currentMoveSpeed; } set { //checa se o valor mudou if(currentMoveSpeed != value) { currentMoveSpeed = value; Debug.Log("speed increased"); if(GameManager.instance !=null) { GameManager.instance.currentMoveSpeedDisplay.text = "Velocidade: " + currentMoveSpeed; } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } public float CurrentMight { get { return currentMight; } set { //checa se o valor mudou if(currentMight != value) { currentMight = value; if(GameManager.instance !=null) { GameManager.instance.currentMightDisplay.text = "Might: " + currentMight; } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } public float CurrentProjectileSpeed { get { return currentProjectileSpeed; } set { //checa se o valor mudou if(currentProjectileSpeed != value) { currentProjectileSpeed = value; if(GameManager.instance !=null) { GameManager.instance.currentProjectileSpeedDisplay.text = "Projectile Speed: " + currentProjectileSpeed; } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } public float CurrentMagnet { get { return currentMagnet; } set { //checa se o valor mudou if(currentMagnet != value) { currentMagnet = value; if(GameManager.instance !=null) { GameManager.instance.currentMagnetDisplay.text = "Magnet: " + currentMagnet; } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } public float CurrentProjectileDuration { get { return currentProjectileDuration; } set { //checa se o valor mudou if(currentProjectileDuration != value) { currentProjectileDuration = value; //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } } #endregion //experiencia e level do jogador [Header("Experience/Level")] public int experience = 0; public int level = 1; public int experienceCap; //muda todo level //faz com que os campos sejam editaveis no unity e tambem pode ser salvo e editado em arquivos (data) [System.Serializable] public class LevelRange { public int startLevel; public int endLevel; public int experienceCapIncrease; } //iframes [Header("I-Frames")] public float invincibilityDuration; float invincibilityTimer; bool isInvincible; public List<LevelRange> levelRanges; InventoryManager inventory; public int weaponIndex; public int passiveItemIndex; public GameObject secondWeaponTest; public GameObject firstPassiveItemTest, secondPassiveItemTest; void Awake() { characterData = CharacterSelector.GetData(); CharacterSelector.instance.DestroySingleton(); inventory = GetComponent<InventoryManager>(); CurrentHealth = characterData.MaxHealth; CurrentRecovery = characterData.Recovery; CurrentMoveSpeed = characterData.MoveSpeed; CurrentMight = characterData.Might; CurrentProjectileSpeed = characterData.ProjectileSpeed; CurrentProjectileDuration = characterData.ProjectileDuration; CurrentMagnet = characterData.Magnet; //spawna a arma inicial SpawnWeapon(characterData.StartingWeapon); SpawnWeapon(secondWeaponTest); SpawnPassiveItem(firstPassiveItemTest); SpawnPassiveItem(secondPassiveItemTest); } void Start() { //Inicializa o cap de xp como o primeiro aumento de cap de xp experienceCap = levelRanges[0].experienceCapIncrease; //seta o valor inicial dos itens GameManager.instance.currentHealthDisplay.text = "Current Health: "+ currentHealth; GameManager.instance.currentRecoveryDisplay.text = "Current Recovery: "+ currentRecovery; GameManager.instance.currentMoveSpeedDisplay.text = "Current Move Speed: "+ currentMoveSpeed; GameManager.instance.currentMightDisplay.text = "Current Might: "+ currentMight; GameManager.instance.currentProjectileSpeedDisplay.text = "Current Projectile Speed: "+ currentProjectileSpeed; GameManager.instance.currentMagnetDisplay.text = "Current Magnet: "+ currentMagnet ; } void Update() { if (invincibilityTimer > 0) { invincibilityTimer -= Time.deltaTime; } else if (isInvincible) { isInvincible = false; } Recover(); } public void IncreaseExperience(int amount) { experience += amount; LevelUpChecker(); } void LevelUpChecker() { if (experience >= experienceCap) { Debug.Log("Player leveled up"); level++; experience -= experienceCap; int experienceCapIncrease = 0; foreach (LevelRange range in levelRanges) { if (level >= range.startLevel && level <= range.endLevel) { experienceCapIncrease = range.experienceCapIncrease; break; } } /*experienceCap += experienceCapIncrease; //xp fixo por niveis */ experienceCap = experienceCap + experienceCapIncrease; // xp aumenta a cada nivel o nivel do cap Debug.Log("Valor de xp necessario para o nivel atual: " + experienceCap); /* */ LevelUpChecker(); //verifica novamente me caso de ganhar muito xp de uma vez } } public void TakeDamage(float dmg) { if (!isInvincible) { currentHealth -= dmg; invincibilityTimer = invincibilityDuration; isInvincible = true; if (CurrentHealth <= 0) { Kill(); } } } public void Kill() { Debug.Log("Player died"); } public void RestoreHealth(float amount) { //somente cura se a vida nao estiver cheia if (CurrentHealth < characterData.MaxHealth) { CurrentHealth += amount; //se a cura passar do maximo de vida, fica com a vida cheia if (CurrentHealth > characterData.MaxHealth) { CurrentHealth = characterData.MaxHealth; } } } void Recover() { if (CurrentHealth < characterData.MaxHealth) { CurrentHealth += CurrentRecovery * Time.deltaTime; } if (CurrentHealth > characterData.MaxHealth) { CurrentHealth = characterData.MaxHealth; } } public void SpawnWeapon(GameObject weapon) { //verifica se os slots estao cheios e retorna if (weaponIndex >= inventory.passiveItemLevels.Length - 1) //troquei count por lenght pq comecou a dar erro (sla???) //verificar depois quando tiver mais armas { Debug.LogError("inventory slots already full"); return; } //arma inicial GameObject spawnedWeapon = Instantiate(weapon, transform.position, Quaternion.identity); spawnedWeapon.transform.SetParent(transform); //faz a arma ser filho do player inventory.AddWeapon(weaponIndex, spawnedWeapon.GetComponent<WeaponController>()); //adiciona a arma para seu slot no inventario weaponIndex++; } public void SpawnPassiveItem(GameObject passiveWeapon) { //verifica se os slots estao cheios e retorna if (passiveItemIndex >= inventory.passiveItemSlots.Count - 1) { Debug.LogError("inventory slots already full"); return; } //arma inicial GameObject spawnedPassiveItem = Instantiate(passiveWeapon, transform.position, Quaternion.identity); spawnedPassiveItem.transform.SetParent(transform); //faz a arma ser filho do player inventory.addPassiveItem(passiveItemIndex, spawnedPassiveItem.GetComponent<PassiveItem>()); //adiciona a arma para seu slot no inventario passiveItemIndex++; } }
GameManager.cs
using UnityEngine; using UnityEngine.UI; public class GameManager : MonoBehaviour { public static GameManager instance; //define os diferentes estados do jogo public enum GameState { Gameplay, Paused, GameOver } //estado atual do jogo public GameState currentState; //guarda o estado anterior do jogo public GameState previousState; [Header("UI")] public GameObject pauseScreen; //current stats display public Text currentHealthDisplay; public Text currentRecoveryDisplay; public Text currentMoveSpeedDisplay; public Text currentMightDisplay; public Text currentProjectileSpeedDisplay; public Text currentMagnetDisplay; void Awake() { //warning check to see if theres another singleton of this kind in the game if(instance == null) { instance = this; } else { Debug.LogWarning("EXTRA "+ this +"DELETED"); Destroy(gameObject); } DisableScreens(); } void Update() { switch (currentState) { //define o padrao de comportamento para cada estado de jogo case GameState.Gameplay: //codigo para quanto o jogo tiver rodando CheckForPauseAndResume(); break; case GameState.Paused: //codigo para quando o jogo estiver pausado CheckForPauseAndResume(); break; case GameState.GameOver: //codigo para quando o estiver gameover break; default: Debug.LogWarning("estado nao existe"); break; //em vez de update fazer um callback para } } //define um metodo para trocar o estado do jogo public void ChangeState(GameState newState) { currentState = newState; } public void PauseGame() { if(currentState != GameState.Paused) { previousState = currentState; ChangeState(GameState.Paused); Time.timeScale = 0f; pauseScreen.SetActive(true); Debug.Log("Game is paused!"); } } public void ResumeGame() { if(currentState == GameState.Paused) { ChangeState(previousState); Time.timeScale= 1f; pauseScreen.SetActive(false); Debug.Log("Game is resumed"); } } //metodo para verificar input de pausa/resume void CheckForPauseAndResume() { if(Input.GetKeyDown(KeyCode.Escape)) { if(currentState == GameState.Paused) { ResumeGame(); } else { PauseGame(); } } } void DisableScreens() { pauseScreen.SetActive(false); } }
March 18, 2025 at 7:11 am #17556::Based on the reference information and the code provided, the issue is likely in the
Start()
method of thePlayerStats
script. The code is setting the initial text for the UI elements, but it does not update dynamically as the stats change.The properties in the
PlayerStats
script (likeCurrentHealth
,CurrentRecovery
, etc.) are correctly set up to update the UI when their values change. However, to ensure the initial values are displayed correctly, you should modify theStart()
method to use the property setters instead of directly setting the text:void Start() { //Use property setters to trigger UI updates CurrentHealth = currentHealth; CurrentRecovery = currentRecovery; CurrentMoveSpeed = currentMoveSpeed; CurrentMight = currentMight; CurrentProjectileSpeed = currentProjectileSpeed; CurrentMagnet = currentMagnet; }
This change will ensure that the UI is updated with the initial stat values using the same mechanism used when stats change during gameplay.
March 18, 2025 at 7:36 am #17557::Did it but still, dont update
void Start() { CurrentHealth = currentHealth; CurrentRecovery = currentRecovery; CurrentMoveSpeed = currentMoveSpeed; CurrentMight = currentMight; CurrentProjectileSpeed = currentProjectileSpeed; CurrentMagnet = currentMagnet; experienceCap = levelRanges[0].experienceCapIncrease; }
and aparently, as i was trying to find the bug, i find out that i messed the damage/health player system when i get hit by an enemy, the life of the player goes to 1030 and stays there, it should reduce 30, and keep reducing but instead it goes up
March 18, 2025 at 7:41 am #17558::It looks like you’re experiencing an issue with the player’s health not updating correctly when they take damage. Here are a few things to check and some suggestions to help you debug the problem:
-
Check the Damage Calculation: Ensure that the code responsible for applying damage to the player’s health is correctly subtracting the damage value. It might look something like this:
public void TakeDamage(int damage) { CurrentHealth -= damage; // This should reduce health CurrentHealth = Mathf.Max(CurrentHealth, 0); // Ensure health doesn't go below 0 }
Make sure that
TakeDamage
is being called correctly and that thedamage
value is what you expect. -
Initialization Errors: Double-check how
currentHealth
is initialized. IfcurrentHealth
is set incorrectly (for example, if it’s being set to a value that is higher than you expect), this could be why you’re seeing health increase instead of decrease. -
Check for Multiple Calls: Verify that
TakeDamage
is not being called multiple times unintentionally. You can add debug logs to see how many times and with what values the function is being called:public void TakeDamage(int damage) { Debug.Log("Taking damage: " + damage); CurrentHealth -= damage; CurrentHealth = Mathf.Max(CurrentHealth, 0); Debug.Log("Current Health: " + CurrentHealth); }
-
Look for Other Modifications: Make sure there aren’t other parts of your code that modify
CurrentHealth
after you apply damage. For example, if you have a healing function or a buff that is activated immediately after taking damage, this could lead to the observed behavior. -
Debugging with Breakpoints: If you’re using an IDE that supports debugging (like Visual Studio), consider setting breakpoints to inspect the values of variables and understand the flow of execution when damage is applied.
-
Check Other Systems: If you have other systems that interact with the player’s health (such as a health regeneration system or power-ups), ensure that they are functioning as expected and not inadvertently increasing health.
If you provide more context or code snippets related to how damage is applied or how health is managed, I could offer more targeted help.
March 18, 2025 at 7:06 pm #17565March 18, 2025 at 11:30 pm #17566::I dont think thats the case since the damage to the player is broken as i said above
“and aparently, as i was trying to find the bug, i find out that i messed the damage/health player system when i get hit by an enemy, the life of the player goes to 1030 and stays there, it should reduce 30, and keep reducing but instead it goes up”
there’s the inspector of GameManager is there something im missing?
some more context (may be useful):
March 19, 2025 at 6:01 pm #17580::i made it to the final part o the ui (around 35:40) of the part 9. but it didnt work, my text ui didnt change at any moment, i did everything correctly and revised a couple times i think theres something wrong in my script, but i cant seem to find it at first when i tested, it didnt work, i resumed the tutorial to see if it would fix when he changed, but still didnt work here’s my code PlayerStats.cs
Can you clarify which text ui you are referring to (highlighted above)?
March 19, 2025 at 10:14 pm #17583::none of the Stats on Pause Screen get updated, when i start playing, neither when it changes (lvl up) it dont update, stay “Current Health Display” and etc
March 20, 2025 at 6:14 pm #17586::Can you add the highlighted portion below to your code in
PlayerStats
?#region Current Stats Properties public float CurrentHealth { get { return currentHealth; } set { //checa se o valor mudou if(currentHealth != value) { currentHealth = value; if(GameManager.instance != null) { GameManager.instance.currentHealthDisplay.text = "Health: " + currentHealth; print("Updated health in current health display"); } else { print("GameManager.instance is null"); } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } }
public float CurrentMight { get { return currentMight; } set { //checa se o valor mudou if(currentMight != value) { currentMight = value; if(GameManager.instance !=null) { GameManager.instance.currentMightDisplay.text = "Might: " + currentMight; print("Updated health in current health display"); } else { print("GameManager.instance is null"); } //da update em tempo real daquele valor //adicione qualquer logica aqui que vai ser executada quando o valor mudar } } }
Then open the pause screen and show me what are the messages in your Console when you open the pause screen.
March 20, 2025 at 8:10 pm #17587 -
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: