您的位置:首页 > 移动开发 > Unity3D

Unity3D+moba+小地图视野

2016-05-05 02:33 399 查看

1功能描述

敌方出现在我方视野中,小地图显示敌方icon。丢失敌方时,icon消失。类似moba游戏,要满足以下要点:

1.所有己方单位自身都要在小地图上显示。

2.所有己方单位共享视野,当有敌方出现在某个己方单位的视野中时,小地图上显示这个敌方icon。

3.敌方一旦丢失在所有己方单位视野中,小地图上icon消失。

2 详细设计

总体思路是对地形分成二维数组int
[
,作为己方的视野权值打分。每个单位所在的世界坐标转化为在地形数组中坐标x,y,每个己方单位的视野以自身为中心探测到格子。每帧检测,上一帧的该单位探测到所有小方块权值-1,当前帧该单位探测到小方块权值+1。当敌人的x,y落在在权值>0的小方块中,说明被探测到了(被谁探测到了不管,己方单位共性视野)。



某一帧,我的视野包括的小方块(绿色框内包含N个小方块)权值为1,队友视野包块的小方块权值为1,两人重叠的部分为2.只要敌人的x,y在权值>0的小方块,说明要出现在视野中了。

2.1 数据初始化

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:所有需要显示在小地图上的单位(包含敌方和我方)。

2.2单位出生时

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的协同函数.

2.3单位移动时

所有处理在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();
}
}
}

3 运行情况



我没探测到敌方A,敌方B,但队友探测到敌方A了,所以小地图上显示3个点(我,队友,敌方B)。



我移动了探测到了敌方B,所以小地图上显示4个点(我,队友,敌方A,B)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: