问题描述
我的平台游戏有一个默认的“未受伤”时间,我的玩家从受伤状态过渡到正常状态;我认为正常时间是 0.54 秒。但是对于特定对象,我希望未受伤的时间更短。我通过将它添加到我未受伤的 IEnumerator 来做到这一点
IEnumerator Unhurt(float? time2)
{
time2 = 4;
SoundMan1.PlayHurtSound();
// SoundMan1.PlayerHurt3.PlayOneshot(SoundMan1.PlayrHurtClips3[Random.Range(0,3)]);
Debug.Log("Unhurting!");
if(time2 == null)
{
} if(time2 > .02f && time2!=null)
{
yield return new WaitForSeconds(time2);
}
else
{
yield return new WaitForSeconds(unhurttime);
}
IsHurt = false;
rb.constraints = RigidbodyConstraints2D.None;
rb.constraints = RigidbodyConstraints2D.FreezeRotation;
Debug.Log("Unhurt");
}
在我的spike脚本中(我从中调用这个协程的脚本。)这是调用它的代码..
collision.gameObject.GetComponent<Player>().StartCoroutine("Unhurt");
我想要这样,如果我在“Unhurt”之后不写任何东西,那么 time2 会浮动吗?将为空,它只会等待默认持续时间。问题是 WaitForSeconds(time2);有错误。它说不能转换浮点数?漂浮。
如果我在“Unhurt”之后添加 .2f 或其他任何内容并将其作为 time2 传递,我希望浮点数不为空,然后它将等待新的持续时间。
解决方法
不,你不能!
正如错误告诉您 WaitForSeconds
期望 float
。
您传入的 float?
只是 Nullable<float>
的同义词,后者是完全不同的类型。
您想要的是 time2.Value
。在访问它之前,您应该检查 time2.HasValue
而不是 == null
(在内部,==
无论如何都使用 HasValue
,因此只会更贵)。
现在在你的代码中有很多悬而未决的问题。
为什么在方法的顶部你做的第一件事就是覆盖
time2 = 4;
无论如何,所以你完全忽略传入的任何值?我想您只会在没有传入任何值的情况下才想要这样做。
然后你检查
if(time2 > .02f && time2!=null)
{
yield return new WaitForSeconds(time2);
}
因此,在您甚至检查它是否具有值之前,您已经想将其与 0.02
进行比较。如果没有上面提到的分配,您应该检查订单
if(time2.HasValue && time2.Value > 0.02f)
{
yield return new WaitForSeconds(time2.Value);
}
我想要这样,如果我在“Unhurt”之后不写任何东西,那么 time2 会浮动吗?将为空
您所说的称为 optional parameter 并要求您实际分配一个默认值,而宁愿看起来像例如
IEnumerator Unhurt(float? time2 = null)
但是为此您不需要任何可空值。为什么不简单地给它一个默认值而不使用像
这样的可空值IEnumerator Unhurt(float time2 = 4f)
这一次,如果您不明确传入任何值,它将始终具有默认值 4
。
最后,总的来说,为了让您的生活更轻松不要使用 StartCoroutine
的字符串版本!
宁愿有一个方法像
public void StartUnhurt(float time2 = 4f)
{
StartCoroutine (Unhurt(time2));
}
并像使用它一样
collision.gameObject.GetComponent<Player>().StartUnhurt();
或
collision.gameObject.GetComponent<Player>().StartUnhurt(3.5f);