Unity3Dでシミュレーションプロジェクトを作成中に、この困惑している動作に遭遇しました。C#Unity3Dの匿名関数スコープ
基本的には、ループ中の変数を使用してループ内に無名関数を作成し、これらの関数をすべてキューに追加して処理していました。
Unity3D Monobehaviorの好奇心は、最後のループ変数でのみ呼び出されるということです。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class TestDist : MonoBehaviour {
int counter = 0;
// Use this for initialization
void Start() {
List<LOL> lols = new List<LOL>();
lols.Add(new LOL(1));
lols.Add(new LOL(2));
lols.Add(new LOL(3));
List<Func<int>> fs = new List<Func<int>>();
foreach (LOL l in lols)
{
//****** Critical Section *********
Func<int> func =() =>
{
Debug.Log(l.ID); //Prints "3" 3 times instead of
return 0; // "1", "2", "3"
};
//****** Critical Section *********
fs.Add(func);
}
foreach (Func<int> f in fs)
{
f();
}
}
// Update is called once per frame
void Update() {
}
}
class LOL
{
public long ID;
public LOL(long id)
{
ID = id;
}
}
コードはプレーンなVisual Studio Consoleアプリケーションではうまく動作しますが、Unity3Dでは失敗します。最後の値( "3")を1,2,3の代わりに3回印刷することにより、バージョン5.0(バージョン5.0)になります。
私は回避するために様々な方法を試してみましたが、明確な理由もなく働いていた次の次のブロックへのクリティカルセクションを変更 はこの問題を解決:誰かが(ユニティバグ修正チームにはない答えることができるかどう
LOL another = l;
Func<int> func =() =>
{
Debug.Log(another.ID);
return 0;
};
は喜んだろう