[英]C# - Loop executes code on all members of array at once instead of iterating through one at a time
我正在 Unity 中制作一个小拳击游戏。 我设计了一个 function(attackOverdrive)来接受一整套 arguments,然后让敌方拳击手根据输入 function 的数据进行攻击。我还有另一个 class,它设置了一堆变量,然后我读取这些值,分配它们到局部变量,然后运行我的 function。事情是我循环中的代码在数组的所有成员上执行,而不是一次迭代一个,导致敌人一次抛出许多攻击,这些攻击是为了依次抛出。 punchDelayTimer 应该计数到一个限制,然后发送消息以实例化攻击,然后循环并再次执行。
我快疯了,尝试了所有不同类型的迭代器,但一无所获。 我是 C# 的新手,不知道我在这里做错了什么。 在另一个脚本中设置变量的 function 位于代码块的底部。
using UnityEngine;
using System.Text.RegularExpressions;
public class overdrivePiano : MonoBehaviour
{
private GameObject enemyBoxer;
private pianoRoll theRoll;
private string theCoordMod;
private string[] thePatterns;
private int howMany;
private float thePunchDelay, thePatternDelay, theCoordModAmount, punchDelayTimer, patternDelayTimer;
private Vector2[] theCoords;
void Start()
{
enemyBoxer= GameObject.Find("enemyBoxer");
theRoll = gameObject.GetComponent<pianoRoll>();
punchDelayTimer = 0;
}
private void readRoll()
{
thePatterns = theRoll.patterns;
thePunchDelay = theRoll.punchDelay;
thePatternDelay = theRoll.patternDelay;
theCoords = theRoll.coords;
theCoordMod = theRoll.coordMod;
theCoordModAmount = theRoll.modAmount;
}
public void onSwitch()
{
theRoll.SendMessage("firstVerse");
readRoll();
attackOverdrive(thePatterns, thePunchDelay, thePatternDelay, theCoords);
}
public void attackOverdrive(string[] patterns, float punchDelay, float patternDelay, Vector2[] coords, string coordMod = "none", float modAmount = 0)
{
for(int i = 0; i < patterns.Length; i++)
{
if (patterns[i] == "triangle")
{
int j = 0;
Vector2[] triangleVectors = new Vector2[] {new Vector2(coords[i].x, coords[i].y + 0.75f), new Vector2(coords[i].x - 0.75f, coords[i].y - 0.75f), new Vector2(coords[i].x + 0.75f, coords[i].y - 0.75f)};
do
{
if (punchDelayTimer <= punchDelay)
{
punchDelayTimer += Time.deltaTime; //Debug statement here for i and j both print 0
}
else
{
enemyBoxer.SendMessage("createAttack", triangleVectors[j]);
punchDelayTimer = 0; //Debug statement here outputs 9 statements for the value of i: 0,0,0,1,1,1,2,2,2
j += 1; //Debug statement here outputs 9 statements for the value of j: 0,1,2,0,1,2,0,1,2
}
} while (j < 3);
}
else if (patterns[i] == "square")
{
}
else if (patterns[i] == "circle")
{
}
else if ("verticalLine".CompareTo(patterns[i]) == -1)
{
var result = Regex.Match(patterns[i], @"\d+$", RegexOptions.RightToLeft);
if (result.Success)
{
//Debug.Log(result.Value);
}
}
}
}
}
private void firstVerse()
{
patterns = new string[] {"triangle", "triangle", "triangle", "singleRandom", "singleRandom", "verticalLine5"};
coords = new Vector2[] {new Vector2(-1.3f, 2.5f), new Vector2(0f, -2.5f), new Vector2(1.3f, 2.5f), new Vector2(0,0), new Vector2(0,0), new Vector2(0, 4f)};
punchDelay = 0.5f;
patternDelay = 0.5f;
}
原来浮动计时器是问题所在。 它正确地遍历了数组,但它们都发生在同一帧上。 我能够通过将 attackOverdrive 的返回类型更改为 IEnumerator 然后将其作为协程从 OnSwitch 调用来解决问题。 我删除了循环三角形部分内的 if 语句,并用 Unity 的 WaitForSeconds class 替换了浮点计时器。以下是更改的函数,以防有人感兴趣:
public void onSwitch()
{
theRoll.SendMessage("firstVerse");
readRoll();
StartCoroutine(attackOverdrive(thePatterns, thePunchDelay, thePatternDelay, theCoords));
}
public IEnumerator attackOverdrive(string[] patterns, float punchDelay, float patternDelay, Vector2[] coords, string coordMod = "none", float modAmount = 0)
{
for(int i = 0; i < patterns.Length; i++)
{
if (patterns[i] == "triangle")
{
int j = 0;
Vector2[] triangleVectors = new Vector2[] {new Vector2(coords[i].x, coords[i].y + 0.5f), new Vector2(coords[i].x - 0.5f, coords[i].y - 0.5f), new Vector2(coords[i].x + 0.5f, coords[i].y - 0.5f)};
do
{
enemyBoxer.SendMessage("createAttack", triangleVectors[j]);
yield return new WaitForSeconds(punchDelay);
punchDelayTimer = 0f;
j += 1;
} while (j < 3);
}
else if (patterns[i] == "square")
{
}
else if (patterns[i] == "circle")
{
}
else if ("verticalLine".CompareTo(patterns[i]) == -1)
{
var result = Regex.Match(patterns[i], @"\d+$", RegexOptions.RightToLeft);
if (result.Success)
{
Debug.Log(result.Value);
}
}
else if ("single".CompareTo(patterns[i]) == -1)
{
var result = Regex.Match(patterns[i], @"\d+$", RegexOptions.RightToLeft);
if (result.Success)
{
Debug.Log(result.Value);
}
}
}
}
感谢 Unity 论坛上的 rage_co,他向我展示了这个修复 =]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.