【问题标题】:Cannot convert type FLOAT into INT when changing sprites更改精灵时无法将 FLOAT 类型转换为 INT
【发布时间】:2019-12-06 01:25:12
【问题描述】:

我正在制作一个精灵表,它会根据我的角色的 HP 而变化。为了创建它,我有一个 Heart 文件,它从玩家那里获取 Health 对象并根据 Current Health 更改精灵。

当我试图将当前健康状况放入 PlayerStats 时。我有一个生命值和最大生命值的浮点数,但显然,要显示精灵,curHealth 必须是一个 INT。

但每当我尝试与 curHealth 值交互时,我都会收到错误消息“无法将类型 'float' 隐式转换为 'int'。

我的心档案

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];
  }
}

playerStats 文件

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);
    }
  }
}

虽然将它与“浮动健康”组件连接起来会更容易。因为它必须是一个 int 这似乎不起作用。 到目前为止,我不知道如何使 curHealth 与这两个文件交互。

【问题讨论】:

  • 当我尝试玩游戏并被敌人击中时。我得到“对象引用未设置为对象的实例”,它指的是 HeartUI.sprite = HeartSprites[Mathf.RoundToInt(player.curHealth)];

标签: c# user-interface unity3d 2d


【解决方案1】:

最简单的方法是演员

int intValue = (int) floatValue;

然而,这只是简单地截断了小数点。


Ali Baba's answer 很接近,但您仍然必须将结果转换为 int,因为他提到的所有方法仍然返回 float。例如

int intValue =  (int)Mathf.Floor(floatValue);

最好直接使用int 返回版本,如Mathf.RoundToInt

int intValue = Mathf.RoundToInt(floatValue);

1.5 -> 2
1.3 -> 1

或者Mathf.FloorToInt 取决于您的需求。

1.9 -> 1
1.2 -> 1


但是,您实际上从未在任何地方更改 curHealth 的值(Start 除外 .. 您应该将其实现为基于 int 的只读属性返回 int 值:

public int CurrentHealth
{
    get { return Mathf.RoundToInt(health); }
}

因此您只需使用float 操作更新healthCurrentHealth 会自动返回相应的int 值。

然后使用

HeartUI.sprite = HeartSprites[player.CurrentHealth];

我不会在 Update 中这样做,而是在 health 实际更改时基于事件 -> 调用方法或将精灵设置移动到同一组件中。

【讨论】:

  • 感谢您的帮助,但由于 curHealth 与我的 playerStats 文档中的“健康”相同。我怎样才能在这里记录差异?因为如果我在启动功能中放置任何带有 curHealth 的内容,我会不断收到错误?如果我将 curHealth 重定向为与 Health 相同,会不会更容易?然后使用可以是小数的健康值?
  • 我试过你的想法,但由于某种原因它仍然给我同样的错误。因为我仍然需要与 playerStats 文件中的“curHealth”值交互/
【解决方案2】:

你得到的错误是指这一行:

curHealth = maxHealth;

你声明

public int curHealth;
public float maxHealth;

正如编译器所说,您不能将float 隐式转换为int。您需要进行显式转换。

如果您将违规行更改为

curHealth = (int)maxHealth;

脚本编译没有错误。

关于 cmets 中的其他建议,Mathf.Floor()返回一个浮点数,所以你又回到了起点,需要显式转换它(int)Mathf.Floor() Microsoft C# 在线文档指出,在显式转换(int)myFloat 中“源值向零舍入到最接近的整数值,并且该整数值成为转换的结果”。 因此,恕我直言,调用(int)Mathf.Floor() 是不必要的,而且浪费资源。 如果您需要以其他方式对其进行舍入,则例如调用(int)Mathf.Ceil() 确实是正确的方法。

【讨论】:

    【解决方案3】:

    我已通过将浮点数更改为 Int 来解决此问题。 我删除了 curHealth 的整个概念并放入了

    HeartUI.sprite = HeartSprites[player.health];
    

    为了使整数工作,我把 (int) 放在下面的示例中

      public void DealDamage(float damage)
      {
        health -= (int) damage;
        CheckDeath();
      }
    
      public void HealCharacter(float heal)
      {
        health += (int) heal;
        CheckOverheal();
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多