我刚刚使用F#开始使用Unity3D,我注意到coroutines在书籍和教程中被大量使用,作为解决各种问题的简洁解决方案。我一直试图弄清楚F#是否具有相同的内置结构,或者它是否至少可能以某种方式模仿它们,但我在MSDN上找不到任何东西。我只使用Continuation monad找到了一些使用协同程序实现的文章,但这些作为初学者已经超出了我的想法。
以下是Unity文档中的C#示例,在游戏循环中重复调用时会导致对象的alpha颜色随着时间的推移逐渐淡化:
IEnumerator Fade() {
for (float f = 1f; f >= 0; f -= 0.1f) {
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield return;
}
}
所以我只需要声明一个返回IEnumerator的函数,然后在“body”中将控件放在body中的任何地方。我不知道如何在F#中执行此操作,因为我不断收到错误“此表达式应该具有类型IEnumerator但这里有类型单位”。 “yield”关键字在F#中的行为也似乎不同,因为与C#不同,它不能单独使用,必须在序列表达式中,正如我从文档中所理解的那样。
所以我错过了什么?如何在F#中实现上述功能?
古斯塔沃的解释是正确的。这是一个精确的Unity脚本,您可以将其附加到一个对象,以便在10秒的时间范围内看到它的红色值减少0.1。
namespace CoroutinesExample
open UnityEngine
type CoroutinesExample() =
inherit MonoBehaviour()
member this.Start() =
// Either of the these two calls will work
// this.StartCoroutine("Fade") |> ignore
this.Fade()
member this.Fade() =
seq {
for f in 1.f .. -0.1f .. 0.f do
let mutable c = this.renderer.material.color
c.r <- f
this.renderer.material.color <- c
yield WaitForSeconds(1.f)
} :?> IEnumerator
This article非常有助于解释Unity中协同程序的详细信息。
答案 0 :(得分:6)
等效的F#代码如下:
member this.Fade() =
seq {
for f in 1.0 .. -0.1 .. 0.0 do
let c = renderer.material.color
c.alpha <- f
renderer.material.color <- c
yield ()
} :> IEnumerable
请注意,与C#不同,您必须产生一些值,因此我们使用单位(()
)。 seq
表达式的类型为seq<unit>
,这是IEnumerable<Unit>
的别名。为了使其符合Unity所期望的类型,我们只需要使用:> IEnumerable