gpt4 book ai didi

C# lambda 调用 for 循环引用最后一个对象

转载 作者:行者123 更新时间:2023-11-30 20:22:50 26 4
gpt4 key购买 nike

我研究了这个问题,并尝试按照之前几个问题中的说明修复代码 (such as this one),但它仍然无法正常工作。虽然我必须说我检查的所有答案都是从 2009 年到 2010 年的,所以它们可能已经过时了。

这是罪魁祸首代码:

            foreach(Entity player in players)
{
if(player.actions.Count > 0)
{
Entity temp = player;

player.isDoingAction = true;
Debug.Log(player.name + " started action");

player.actions.Dequeue().Execute(() => { temp.isDoingAction = false; Debug.Log(temp.name + " finished"); });
}
}

这将打印以下内容:

Player1 started action
Player2 started action
Player2 finished
Player2 finished

什么时候应该打印:

Player1 started action
Player2 started action
Player1 finished
Player2 finished

或类似的东西。

此代码在 Unity 协程函数中运行。

代码的大一点:

GameManager.cs

private IEnumerator RunTurn()
{
...
...
...

for(int i = 0; i < phases; i++)
{
//Assign action to each player
foreach(Entity player in players)
{
if(player.actions.Count > 0)
{
Entity temp = player;

player.isDoingAction = true;
Debug.Log(player.name + " started action");
player.actions.Dequeue().Execute(() => { temp.isDoingAction = false; Debug.Log(temp.name + " finished"); });
}
}

//Wait for each player to finish action
foreach(Entity player in players)
{
while(player.isDoingAction == true)
{
Debug.Log("Waiting for " + player.name);
yield return null;
}
}
}

...
...
...
}

Action.cs

public override void Execute(System.Action callback)
{
Move(callback);
}

private void Move(System.Action callback)
{
...
...
...

//Move target entity
target.MoveToPosition(newPosition, mSpeed, callback);
target.location = newLocation;

...
...
...
}

Entity.cs

public void MoveToPosition(Vector3 position, float speed, System.Action callback)
{
StartCoroutine(CoMoveToPosition(position, speed, callback));
}

//Move to position
private IEnumerator CoMoveToPosition(Vector3 position, float speed, System.Action callback)
{
while(position != transform.position)
{
transform.position = Vector3.MoveTowards(transform.position, position, speed * Time.deltaTime);
yield return null;
}

//Move finished so use callback
callback();
}

解决方案

事实证明,Unity 中存在协程和匿名 lambda 回调的错误。检查this更多链接。

工作代码:

foreach(Entity player in players)
{
if(player.actions.Count > 0)
{
player.isDoingAction = true;
Debug.Log(player.name + " started action");

System.Func<Entity, System.Action> action = new System.Func<Entity,System.Action>(p =>
new System.Action(() => { p.isDoingAction = false; Debug.Log(p.name + " finished"); }));

player.actions.Dequeue().Execute(action(player));
}
}

最佳答案

您可以通过以下方式捕获值:

var action = new Func<Entity, Action>(p => 
new Action(() => { p.isDoingAction = false; Debug.Log(p.name + " finished")); })(player);
player.actions.Dequeue().Execute(action);

关于C# lambda 调用 for 循环引用最后一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30436227/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com