做三消项目需要做一个提示用户哪个格子可以消除的功能,需要对整个棋盘进行遍历。
原来没用协程的代码
public void GetTip()
{
GameObject go1, go2;
int[] way = { 1, -1, -10, 10 };
int max = (xl - 1) * 10 + yl - 1;
for (int x = 0; x < xl; x += 2)
{
for (int y = 0; y < yl; y++)
{
int gid = GetGridID(x, y);
for (int i = 0; i <= 3; i++)
{
int newGid = gid + way[i];
if (newGid <= max && newGid >= 0 && newGid % 10 < yl)
{
Swap(ref DicGrid[newGid].GridType, ref DicGrid[gid].GridType);
if (ComparatorTip(newGid))
{
go1 = DicGrid[gid].gameObject;
go2 = DicGrid[newGid].gameObject;
HighLight(go1);
HighLight(go2);
Swap(ref DicGrid[newGid].GridType, ref DicGrid[gid].GridType);
return;
}
else Swap(ref DicGrid[newGid].GridType, ref DicGrid[gid].GridType);
}
}
}
}return ;
}
代码很多,只看重点,代码里的二重循环对游戏主循环有很大影响,每次用户点击按钮都要卡一下,但是unity不允许在这种地方用多线程,所以,只能改成协程,让这个功能分几个帧完成,就可以感觉不到卡顿。
修改后的代码
public void GetTipGo()
{
StartCoroutine("IGetTipGo");
}
IEnumerator IGetTipGo()
{
GameObject go1, go2;
int[] way = { 1, -1, -10, 10 };
int max = (xl - 1) * 10 + yl - 1;
for (int x = 0; x < xl; x += 2)
{
for (int y = 0; y < yl; y++)
{
int gid = GetGridID(x, y);
for (int i = 0; i <= 3; i++)
{
int newGid = gid + way[i];
if (newGid <= max && newGid >= 0 && newGid % 10 < yl)
{
yield return 0;
Swap(ref DicGrid[newGid].GridType, ref DicGrid[gid].GridType);
if (ComparatorTip(newGid))
{
yield return 0;
go1 = DicGrid[gid].gameObject;
go2 = DicGrid[newGid].gameObject;
HightLight(go1);
HighLight(go2);
Swap(ref DicGrid[newGid].GridType, ref DicGrid[gid].GridType);
StopCoroutine("IGetTipGo");
}
else Swap(ref DicGrid[newGid].GridType, ref DicGrid[gid].GridType);
}
}
}
}
StopCoroutine("IGetTipGo");
}
用两个yield return 0;将几个比较耗时间的运算用帧分开,原来的return改为StopCoroutine();
这样就可以释放主循环的压力了。
PS:进阶技巧
协程与多线程的结合
参考博客
http://blog.csdn.net/laipixiaoxi/article/details/51890903