敌方出现在我方视野中,小地图显示敌方icon。丢失敌方时,icon消失。类似moba游戏,要满足以下要点:
1.所有己方单位自身都要在小地图上显示。
2.所有己方单位共享视野,当有敌方出现在某个己方单位的视野中时,小地图上显示这个敌方icon。
3.敌方一旦丢失在所有己方单位视野中,小地图上icon消失。
总体思路是对地形分成二维数组int[N][[N],作为己方的视野权值打分。每个单位所在的世界坐标转化为在地形数组中坐标x,y,每个己方单位的视野以自身为中心探测到格子。每帧检测,上一帧的该单位探测到所有小方块权值-1,当前帧该单位探测到小方块权值+1。当敌人的x,y落在在权值>0的小方块中,说明被探测到了(被谁探测到了不管,己方单位共性视野)。
某一帧,我的视野包括的小方块(绿色框内包含N个小方块)权值为1,队友视野包块的小方块权值为1,两人重叠的部分为2.只要敌人的x,y在权值>0的小方块,说明要出现在视野中了。
void viewDataInit() { m_gridLen = (int)(m_mapSize / m_gridSize); m_gridCampUnitCnt = new int[m_gridLen, m_gridLen]; m_gridUnitInView = new List<UnitCtrl>(); for (int i = 0; i < m_gridLen; i++) { for (int j = 0; j < m_gridLen; j++) { m_gridCampUnitCnt[i, j] = 0; } } }
m_mapSize:地形尺寸。m_gridSize:每个格子的世界坐标大小。m_gridCampUnitCnt:权值二维数组。m_gridUnitInView:所有需要显示在小地图上的单位(包含敌方和我方)。
public void Respawn(UnitCtrl unitCtrl) { m_unitCtrl = unitCtrl; m_gridSize = MainMgr.self.m_gridSize;//每一格所占的尺寸(世界坐标) m_gridViewXLen = (int) (m_unitCtrl.m_viewXLen/m_gridSize);//我x方向上能看到的格子数量 m_gridViewYLen = (int) (m_unitCtrl.m_viewYLen/m_gridSize); m_gridX = (int)(m_unitCtrl.transform.position.x/m_gridSize); m_gridY = (int) (m_unitCtrl.transform.position.z/m_gridSize); if (MainMgr.self.isInRange(m_gridX) && MainMgr.self.isInRange(m_gridY)) {(MainMgr.self.m_gridAllUnit[m_gridX,m_gridY]).Add(m_unitCtrl);} m_maxLen = MainMgr.self.m_gridLen - 1; if (m_unitCtrl.m_camp == MainMgr.self.m_camp)//如果是同一阵营的,unit视野下的方块权值+1 { for (int x = m_gridX - m_gridViewXLen; x <= m_gridX + m_gridViewXLen; x++) { if (x >= 0 && x <= m_maxLen) { for (int y = m_gridY - m_gridViewYLen; y <= m_gridY + m_gridViewYLen; y++) { if (y >= 0 && y <= m_maxLen) { MainMgr.self.m_gridCampUnitCnt[x, y]++;//权值加1 } } } } unitShowInMiniMap(); } StartCoroutine("yieldUpdataGrid"); }
单位出生时,如果是我方阵营时,他包含的所有小格子权值+1,并且自身要显示在小地图上。出生后开启yieldUpdataGrid的协同函数.
所有处理在yieldUpdataGrid中。
当单位为我方阵营时,每个小格子权值的要做改变。
//当前所在格子 int gridX = (int)(m_unitCtrl.transform.position.x / m_gridSize); int gridY = (int)(m_unitCtrl.transform.position.z / m_gridSize); //与上一帧所在格子做比较 int offsetX = gridX - m_gridX; int offsetY = gridY - m_gridY; if (m_unitCtrl.m_camp == MainMgr.self.m_camp) //跟我是同一阵营的,更新地图小格子的权值 { if (offsetX > 0) //向右走 { int left = m_gridX - m_gridViewXLen; int right = m_gridX + m_gridViewXLen + 1; for (int x = 0; x < offsetX; x++) { for (int y = m_gridY - m_gridViewYLen; y <= m_gridY + m_gridViewYLen; y++) { if (MainMgr.self.isInRange(y)) { if (MainMgr.self.isInRange(left + x)) MainMgr.self.m_gridCampUnitCnt[left + x, y]--; if (MainMgr.self.isInRange(right + x)) MainMgr.self.m_gridCampUnitCnt[right + x, y]++; } } } } else if (offsetX < 0) //向左走 { int left = m_gridX - m_gridViewXLen - 1; int right = m_gridX + m_gridViewXLen; for (int x = 0; x > offsetX; x--) { for (int y = m_gridY - m_gridViewYLen; y <= m_gridY + m_gridViewYLen; y++) { if (MainMgr.self.isInRange(y)) { if (MainMgr.self.isInRange(right + x)) MainMgr.self.m_gridCampUnitCnt[right + x, y]--; if (MainMgr.self.isInRange(left + x)) MainMgr.self.m_gridCampUnitCnt[left + x, y]++; } } } } if (offsetY > 0) //向上走 { int top = m_gridY + m_gridViewYLen + 1; int bottom = m_gridY - m_gridViewYLen; for (int y = 0; y < offsetY; y++) { for (int x = gridX - m_gridViewXLen; x <= gridX + m_gridViewXLen; x++) { if (MainMgr.self.isInRange(x)) { if (MainMgr.self.isInRange(bottom + y)) MainMgr.self.m_gridCampUnitCnt[x, bottom + y]--; if (MainMgr.self.isInRange(top + y)) MainMgr.self.m_gridCampUnitCnt[x, top + y]++; } } } } else if (offsetY < 0) //向下走 { int top = m_gridY + m_gridViewYLen; int bottom = m_gridY - m_gridViewYLen - 1; for (int y = 0; y > offsetY; y--) { for (int x = gridX - m_gridViewXLen; x <= gridX + m_gridViewXLen; x++) { if (MainMgr.self.isInRange(x)) { if (MainMgr.self.isInRange(top + y)) MainMgr.self.m_gridCampUnitCnt[x, top + y]--; if (MainMgr.self.isInRange(bottom + y)) MainMgr.self.m_gridCampUnitCnt[x, bottom + y]++; } } } } }
主要处理为上一帧的包含的所有小格子权值-1,当前帧包含的所有小格子权值-1.MainMgr.self.isInRange是判断游标有没越界。
当单位为敌方单位时:
if (m_unitCtrl.m_camp != MainMgr.self.m_camp)//如果单位和我是不同阵营的 { if (MainMgr.self.isInRange(gridX) && MainMgr.self.isInRange(gridY)) { if (MainMgr.self.m_gridCampUnitCnt[gridX, gridY] > 0) { unitShowInMiniMap(); } else { unitHideInMinimap(); } } }
我没探测到敌方A,敌方B,但队友探测到敌方A了,所以小地图上显示3个点(我,队友,敌方B)。
我移动了探测到了敌方B,所以小地图上显示4个点(我,队友,敌方A,B)。