Unity3D+moba+小地图视野

来源:互联网 发布:室内平面设计图软件 编辑:程序博客网 时间:2024/04/27 20:55

1功能描述

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

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

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

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

2 详细设计

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


某一帧,我的视野包括的小方块(绿色框内包含N个小方块)权值为1,队友视野包块的小方块权值为1,两人重叠的部分为2.只要敌人的xy在权值>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个点(我,队友,敌方AB)。






0 0
原创粉丝点击