F#中的协同程序

时间:2013-11-06 11:11:01

标签: f# unity3d coroutine

我刚刚使用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中协同程序的详细信息。

1 个答案:

答案 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

进行上传。