Reputation: 99
I am working on a sprite sheet which changes depending on the HP of my character. To create this I have a Heart file which takes the Health object from the player and changes the sprites depending on the Current Health.
While I'm trying to put Current health within the PlayerStats. I have a float for health and max health but apparently, to display the sprite the curHealth has to be an INT.
but whenever I try to interact with the curHealth value, I keep getting the error " Cannot implicitly convert type 'float' to 'int'.
My Heart file
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Hearts : MonoBehaviour
{
public Sprite[] HeartSprites;
public Image HeartUI;
private PlayerStats player;
void Start (){
player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerStats>();
}
void Update (){
HeartUI.sprite = HeartSprites[player.curHealth];
}
}
The playerStats file
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerStats : MonoBehaviour
{
public static PlayerStats playerStats;
public int curHealth;
public GameObject player;
public float health;
public float maxHealth;
void Awake()
{
if(playerStats != null)
{
Destroy(playerStats);
}
else
{
playerStats = this;
}
DontDestroyOnLoad(this);
}
void Start()
{
health = maxHealth;
curHealth = maxHealth;
}
public void DealDamage(float damage)
{
health -= damage;
CheckDeath();
}
public void HealCharacter(float heal)
{
health += heal;
CheckOverheal();
}
private void CheckOverheal()
{
if(health > maxHealth)
{
health = maxHealth;
}
}
private void CheckDeath()
{
if(health <= 0)
{
Destroy(player);
}
}
}
While it would have been easier to just connect it with the "float health" component. since it HAS to be an int this doesn't seem to work. So far I don't have a clue how i'll be able to make the curHealth interactable with these 2 files.
Upvotes: 0
Views: 389
Reputation: 99
I have fixed this issue by changing the floats into Int's. I deleted the whole concept of curHealth and put in
HeartUI.sprite = HeartSprites[player.health];
In order for the ints to work i put (int) as seen on the examples below
public void DealDamage(float damage)
{
health -= (int) damage;
CheckDeath();
}
public void HealCharacter(float heal)
{
health += (int) heal;
CheckOverheal();
}
Upvotes: 0
Reputation: 90629
Esiest way would be a cast
int intValue = (int) floatValue;
however this simply cuts off the decimals.
Ali Baba's answer was close but you still have to cast the results to int
since all the methods he mentioned still return a float
. E.g.
int intValue = (int)Mathf.Floor(floatValue);
Better would be to directly use the int
returning versions like Mathf.RoundToInt
int intValue = Mathf.RoundToInt(floatValue);
1.5
-> 2
1.3
-> 1
or maybe Mathf.FloorToInt
depedning on your needs.
1.9
-> 1
1.2
-> 1
However you are never actually changing the value of curHealth
anywhere (except in Start
.. you should rather implement it maybe as read-only property returning an int
value based on health
:
public int CurrentHealth
{
get { return Mathf.RoundToInt(health); }
}
so you only have to update health
using float
operations and CurrentHealth
returns the according int
value automatically.
and then use
HeartUI.sprite = HeartSprites[player.CurrentHealth];
I wouldn't do this in Update
though but rather event based in the moment the health
is actually changed -> either call a method or move the sprite setting into the same component.
Upvotes: 3
Reputation: 1102
The error you get refers to this line:
curHealth = maxHealth;
You declared
public int curHealth;
public float maxHealth;
As the compiler says, you cannot implicitly convert a float
to an int
. You need to cast an explicit conversion.
If you change the offending line to
curHealth = (int)maxHealth;
The script compiles without errors.
About the other suggestions in the comments, Mathf.Floor()
returns a float, so you are back to the starting point and need to explicitly cast it (int)Mathf.Floor()
Microsoft C# online documentation states that in the explicit casting (int)myFloat
"the source value is rounded towards zero to the nearest integral value, and this integral value becomes the result of the conversion".
So, calling (int)Mathf.Floor()
is IMHO not necessary, and a waste of resources.
In case you need to round it in other ways, then e.g. calling (int)Mathf.Ceil()
would indeed be the correct way.
Upvotes: 0