mafiaf
mafiaf

Reputation: 99

Cannot convert type FLOAT into INT when changing sprites

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

Answers (3)

mafiaf
mafiaf

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

derHugo
derHugo

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

kefren
kefren

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

Related Questions