精华内容
参与话题
问答
  • 基于Unity3D引擎制作大地图

    千次阅读 2015-01-25 22:22:47
    基于Unity3D引擎制作大地图 1.下载Unity3D: http://www.devzone.cn/thread-17305-1-1.html 2.制做一张灰度图: 需求:Photoshop   GIMP 先Google 搜 WorldMap-A_non-Frame.png 这个地图下载一张到你pc ...


    2.制做一张灰度图:

    需求:Photoshop 
              GIMP

    先Google 搜 WorldMap-A_non-Frame.png  这个地图下载一张到你pc

    然后gimp打开它, 右键图片,弹出菜单——选择——按颜色

    这张图的好处在于海洋就是几种蓝色,按照颜色分别  左键 选取这几个蓝色,按下delete键删除颜色,清理干净后如图


    然后 菜单栏 图像——模式——灰度
    然后 菜单栏  颜色——反向
    保存,用ps打开它,,,,用 滤镜——模糊——高斯模糊

    有个问题需要注意!图像必须是边长相等的正方形!

    做完,这个地图的灰度图一定要  点菜单栏 的编辑——变换——水平变换  (你肯定问为啥要这样!地图反了?对,反了,因为导入raw后会水平翻转,所以你要翻转高度图进引擎才是正的。)
    保存为.raw

    3.地形

    运行,前面怎么可以找找教程,创建完工程后,新的场景里,我们开始地图工作, 左上角找到Create ,菜单里面选 Terrain.



    于是我们得到了一个地形,如下图,找到那个齿轮图标

    我们叫这个图标设置,其他我们不管,找下面的Resolution

    然后Wides 宽度 Length长度 都设置为高度图的边长像素,也就是图片的长宽

    Height可以随时调节,是地图的最大高度。

    然后下面的Import raw...导入咱的高度图,然后弹出小窗口,其他别动,把默认的mac设置为windows.然后import,然后我们的地形就进去了。




    调整到你认为合适吧,然后我们说下如何导出为 obj格式的。。。
    这个我们需要导出脚本了:http://wiki.unity3d.com/index.php?title=TerrainObjExporter

    用法我简单说下吧,懂英语的可以看懂上面网址里面说的用法。
    如下图那是个管理资源的窗口,右侧那个大窗口的空白部分右键一下,菜单里点show in explorer  你发现资源管理器能打开一个文件夹,没错这是在你电脑文件夹里都有的(这一行文字只是让你了解构造。。。
    so。。右键右侧空白部分,菜单里点 create....然后选 c# script 或  java script

    然后如果你用c#了,刚才那个地址里的你就复制c的代码,往里面粘贴(新脚本都有几行代码,全删掉然后再粘贴。) JS 就粘贴JS的。




    然后的菜单栏的就会多一个Terrain选项,点一下选 Export to obj....

    然后没什么了。。。。
        export format  为Triangles    三角形默认的不用碰

        resolution 很重要: 
                               Full  当前地形网格的完整面数
                               Half 当前地形网格面数的一半
                               Quarter  四分之一
                               Eighth    八分之一
                               Sixteenth 十六分之一


    注意: obj地图模型要先导入max,再往max导入一个native的地图的obj(别问我怎么把骑砍地图弄obj导出),对比着骑砍的地图obj旋转 移动 ,校准网格坐标。然后往编辑器导入才能正确。 

    矫正坐标后导出obj到你的编辑器的map data里,然后编辑器就能导入了。。。。

    一般导出后进max看看有几十万面以上的就不要导入编辑器了。。。。

    细节大家自己摸索摸索吧

    还有如果对手绘地图比较偏好的同学,你们可以结合着地图编辑器和unity用,具体你们看看。
    但是纯属手绘的虽然细节你很爽,但是面数你会不爽。。。。


    有些基础的东西我没说那么详细,不过摸索下就会了



    补俩截图: 



    展开全文
  • Unity3d MapMagic World Generator基于节点的程序和无限游戏地图生成器,图形上的每个节点表示地形或对象生成器:噪声,voronoi,混合,曲线,侵蚀,散射,森林等生态系统,一旦节点连接,魔法发生:游戏地图将创建...

    Unity3d游戏地图生成器MapMagic World Generator v1.9.1

     

     

    Unity3d MapMagic World Generator基于节点的程序和无限游戏地图生成器,图形上的每个节点表示地形或对象生成器:噪声,voronoi,混合,曲线,侵蚀,散射,森林等生态系统,一旦节点连接,魔法发生:游戏地图将创建没有任何人类参与。

    无需艰苦的工作雕刻和绘制广的地形,放置成千上万的对象,绘画草地:只是给你的订单到插件的节点图形的形式,它会自动创建一个地图!

    支持多种生物群落:来自不同图形的森林,沙漠,雪平原,丛林和其他地形类型可以混合在一起。

    需要Unity 5.2.1或更高版本。

     

    下载地址:

    https://item.taobao.com/item.htm?id=566849792097

     

    教程:

    https://gitlab.com/denispahunov/mapmagic/wikis/home

    posted on 2018-04-03 06:56 jiahuafu 阅读(...) 评论(...) 编辑 收藏

    展开全文
  • 总览随着RogueLike游戏的火爆,基于像素和砖块(Tile)的游戏类型也再次兴起,而Unity也推出了他们官方的Tile工具——TileMap,但是TileMap默认的Tile是方形的,如果有些开发者(比如我)不想做类似于《节奏地牢》的方形...

    总览

    随着RogueLike游戏的火爆,基于像素和砖块(Tile)的游戏类型也再次兴起,而Unity也推出了他们官方的Tile工具——TileMap,但是TileMap默认的Tile是方形的,如果有些开发者(比如我)不想做类似于《节奏地牢》的方形砖块,而想做类似于《文明》或是《为了国王》的六边形地块,用Unity自带的TileMap该如何实现呢?

    而Unity虽然足够强大,为我们准备好了六边形Tile的接口,但依然有很多需要注意的地方,想要将默认为方形的TileMap转化为六边形的TileMap,在目前最新的Unity版本(2018.3Beta)下,我们往往需要做以下修改:

    将Grid中的Tile类型修改

    根据需要修改Grid中Tile的大小

    修改TileMap锚点的偏移量

    将默认的矩形模式转变为六边形模式

    1.更改Grid中的Tile类型

    可能很多用过TileMap的同学都知道,当我们在一个场景中create一个TileMap节点出来的时候,Unity会自动帮我们生成一个Grid父节点和一个Tilemap子节点。

    我个人的理解是外层的Grid主要是用于设置Tilemap的整个网格的相关属性,而内层的Tilemap主要是设置Tilemap在渲染时的相关属性,是和每个tile块息息相关的设置,而我们现在要调节的是网格单元的形状,那自然是要修改Grid的属性。而修改的内容也很简单,将Cell Layout这个下拉菜单改为Hexagon(六边形)就可以了。

    在做完这一步修改后,你会发现Scene视图下的Tilemap网格已经变成了六边形的。

    2.更改Grid中Tile的大小

    但是如果你觉得这样就大功告成了,那你就错了,你会发现,把美工同学准备的正六边形的图片放进去之后,图片明显比网格单元在纵向上要长!这是为什么呢,原因是正六边形的格子长宽比不是像矩形格子那样显而易见,比如正方形就是1:1,而我们修改了Cell Layout之后,Unity并不会自动帮我们修改这个长宽比,所以我们需要简单的计算一下此时我们需要的长宽比是多少,比如正六边形如下图所示

    所以在经过简单的四舍五入之后,我们把Grid中Tile的大小调成1:1.15就可以得到正六边形的格子了。

    3.修改TileMap锚点的偏移量

    实际上,这时候你如果去拿对应位置的单元格的位置,你会发现,拿到的数据不对,这是其实是因为Unity的Tilemap在转成六边形后因为未知原因需要将Tilemap中的Tile Anchor即锚点改成0,但是并不晓得什么原理,改成这样就对了

    六边形模式下,每个砖块与相邻砖块的关系

    在矩形模式下,想要确定一个砖块的相邻砖块是非常简单的,比如要找出与砖块(1, 1)相邻的8个砖块,我相信没有人不会,那就是(0, 0)、(0, 1)、(0, 2)、(1, 0)、(1, 2)、(2, 0)、(2, 1)、(2, 2)。

    而如果说是六边形情况下的相邻砖块,因为底层也是用的矩阵存储的,但是相邻砖块却只有6个了,这让初次接触的读者可能有点摸不着头脑,所以这6个应该是哪6个呢,让我们来试一试不就好了!

    让我们在基础的生成砖块的代码的基础上,在Update函数中加入如下代码:

    if(Input.GetMouseButtonUp (0)){

    Vector3 mousePositionInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);

    Debug.Log(tilemap.WorldToCell(mousePositionInWorld));

    }

    这样,如果读者已经按笔者之前说的三点调节好了Tilemap的属性的话,在点击界面的时候,在Unity的Console窗口中就会打印出我们当前点击的砖块在Tilemap中的坐标了,而从(1, 1)位置的格子左边那个格开始,顺时针点一圈,得到的打印结果是

    让我们把它转化成矩阵的布局就是

    所以我们只要把这6个偏移量设置为方向偏移,就可以在矩阵数据中正确取到六边形模式下的相邻格啦!!!然后很多小朋友就这么自信的去做了,结果发现得到的效果并不对,比如在实现用键盘控制角色的行走时,经常跳格!(比如笔者我)实际上是因为,这种六边形模式下的相邻格判断,实际上是分奇偶行的,而上面的这六个偏移,只适合y的坐标是奇数的情况下,比如(1, 1),而偶数的情况下,用相同的方法我们可以得到如下偏移量。

    结语

    好啦!!这样我们就可以在六边形的模式下完成所有在矩形模式下的工作啦!!

    我是“玉轮爱玩”,这是我的第一篇技术分享博客,希望大家喜欢,有任何不足也非常希望大家可以告诉我!!

    另外其实我也是个B站的知名啊噗主,搜“玉轮爱玩”就可以找到我的独立游戏开发日志啦!!

    最后再宣一下群,欢迎大家加入我的小家庭——六点的影子(573228201)!!

    展开全文
  • 看到好多小伙伴似乎都想做六边形地图,我刚好在之前的demo里基于Unity3d实现了一个。 六边形地图编辑器怎么弄我就不发了,可以看看TX爸爸出的这篇博客http://gad.qq.com/program/translateview/7173811。 主要是...

    看到好多小伙伴似乎都想做六边形地图,我刚好在之前的demo里基于Unity3d实现了一个。

    六边形地图编辑器怎么弄我就不发了,可以看看TX爸爸出的这篇博客http://gad.qq.com/program/translateview/7173811。

    主要是关于寻路,AStar寻路有很多的优化方法,想要优化什么的自行百度,我就发个基础的代码(哪天我得空了可以再放一下分步讲解)。

    using UnityEngine;
    using System.Collections.Generic;
    using System;
    
    /// <summary>
    /// 六边形地图的A*寻路,在使用时先调用AstarMainFunc方法,之后会根据输入的起始点下表改变路径上需要考虑的cell的父节点;
    /// 之后该方法将父节点从终点寻址储存到移动功能类中;
    /// 因为该节点是从终点寻址到起点,存在先进后出的读取要求,所以推荐用栈存储;
    /// 在存储完后在移动功能类中调用ClearFValueAndGValue方法;
    /// 在ClearFValueAndGValue方法被调用后才可以再进行下一次寻路;
    /// 因此可以有单位同时移动,但不可以有单位同时寻路=》除非所有节点的父节点元素是一个数组;
    /// 如果所有节点的父节点元素是一个数组,则在修改本类源码后,可以有该数组长度的数量的单位同时寻路。
    /// 2017年12月14日 14:07:03
    /// 最后一次修改人:朱珂杰
    /// </summary>
    class AStarMain : MonoBehaviour
    {
        private HexCell[] cellsForAll;
        private List<int> cellsForOpenContainer;
        private List<int> cellsForOpen;
        private List<int> cellsForClose;
        private int currentCellIndex;
        private int hValue;
        /// <summary>
        /// HexGrid中的width,需要在代码中赋值
        /// </summary>
        private int width = 0;
        private int height = 0;
    
        /// <summary>
        /// 某一点四周所有点的集合,第一个是该点右上角的点,然后按照顺时针直至该点左上角,y坐标为-x-z
        /// 以下为备用元素,在地图大改时可能会需要
        /// </summary>
        //private HexCoordinates[] aroundHexCoordinates = {
        //    new  HexCoordinates (0, 1),
        //    new HexCoordinates(1, 0),
        //    new HexCoordinates(1, -1),
        //    new HexCoordinates(0, -1),
        //    new HexCoordinates(-1, 0),
        //    new HexCoordinates(-1, 1),
        //};
        //private int[] aroundHexCellForIndex;
        public void Awake()
        {
            cellsForOpenContainer = new List<int>();
            cellsForOpen = new List<int>();
            cellsForClose = new List<int>();
        }
        public void Start()
        {
            GetCells();
            width = GameObject.Find("HexPlaneRoot").GetComponent<HexGrid>().width;
            height = GameObject.Find("HexPlaneRoot").GetComponent<HexGrid>().height;
            Debug.Log("得到cells");
        }
        private void GetCells()
        {
            cellsForAll = GameObject.Find("HexPlaneRoot").transform.GetComponentsInChildren<HexCell>();
        }
        /// <summary>
        /// 寻路主函数,先不考虑行数很低时的情况;
        /// 在运行结束后,根据cellForEndIndex下标对应的cell的父节点寻踪直至起始点得到路径
        /// </summary>
        /// <param name="cell">起始点</param>
        public void AstarMainFunc(int cellForBeginIndex, int cellForEndIndex)
        {
            //1,将cellForBegin添加到关闭列表
            cellsForClose.Add(cellForBeginIndex);
            currentCellIndex = cellForBeginIndex;
            AddCellsToOpen();
            while (!cellsForOpen.Contains(cellForEndIndex))
            {
                //遍历开放列表找出所有点中F最小的点
                int fValueMinIndexInOpen = 0;
                if (cellsForOpen.Count > 1)
                    for (int i = 1; i < cellsForOpen.Count; i++)
                    {
                        //hValue
                        hValue = cellsForAll[cellForEndIndex].coordinates - cellsForAll[cellsForOpen[i]].coordinates;
                        cellsForAll[cellsForOpen[i]].fValue = cellsForAll[cellsForOpen[i]].gValue + hValue;
                        if (cellsForAll[cellsForOpen[i]].fValue < cellsForAll[cellsForOpen[fValueMinIndexInOpen]].fValue)
                            fValueMinIndexInOpen = i;
                    }
                //将该点添加到关闭列表中
                cellsForClose.Add(cellsForOpen[fValueMinIndexInOpen]);
                //将该点从开放列表移除
                //没做,忘了,记得补=。=
                currentCellIndex = cellsForOpen[fValueMinIndexInOpen];
                cellsForOpen.RemoveAt(fValueMinIndexInOpen);
                AddCellsToOpen();
            }
            cellsForOpenContainer.Clear();
            cellsForOpen.Clear();
            cellsForClose.Clear();
            ClearFValueAndGValue();
        }
        private void ClearFValueAndGValue()
        {
            foreach (HexCell cell in cellsForAll)
            {
                cell.fValue = 0;
                cell.gValue = 0;
            }
        }
        /// <summary>
        /// 清理所有节点的父节点,在储存完栈后,于调用寻路的类中被调用
        /// </summary>
        public void ClearCellsFather()
        {
            foreach (HexCell cell in cellsForAll)
            {
                cell.hexCellFather = null;
            }
        }
        /// <summary>
        /// 添加当前点四周可添加的点进入开放列表,这个方法结束后,会针对新添加的点和重复的点刷新它内部的父节点和gValue;
        /// 在调用此方法前,需要先对当前点的下表进行标定。
        /// </summary>
        private void AddCellsToOpen()
        {
            //行数,0开始计数
            int row = currentCellIndex / width;
            //取出当前点四周所有的新点进入开放列表
            //这些写完后抽象成方法,因为这部分可能随着地图生成频繁修改
            //左列
            if (currentCellIndex % width == 0)
            {
                //底行,加两个
                if (currentCellIndex / width == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex + width);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                }
                //顶行
                if (currentCellIndex / width == height - 1)
                {
                    //偶行,0开始计数,加两个
                    if (row % 2 == 0)
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex + 1);
                    }
                    //奇行,0开始计数,加三个
                    else
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex - width + 1);
                        cellsForOpenContainer.Add(currentCellIndex + 1);
                    }
                }
                //中间行
                if (currentCellIndex / width > 0 && currentCellIndex / width < height - 1)
                {
                    //偶行,0开始计数,加三个
                    if (row % 2 == 0)
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex + 1);
                        cellsForOpenContainer.Add(currentCellIndex + width);
                    }
                    //奇行,0开始计数,加五个
                    else
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex - width + 1);
                        cellsForOpenContainer.Add(currentCellIndex + 1);
                        cellsForOpenContainer.Add(currentCellIndex + width);
                        cellsForOpenContainer.Add(currentCellIndex + width + 1);
                    }
                }
            }
            //右列
            if (currentCellIndex % width == width - 1)
            {
                //底行,加三个
                if (currentCellIndex / width == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex + width);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex + width - 1);
                }
                //顶行
                if (currentCellIndex / width == height - 1)
                {
                    //偶行,0开始计数,加三个
                    if (row % 2 == 0)
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex - 1);
                        cellsForOpenContainer.Add(currentCellIndex - width - 1);
                    }
                    //奇行,0开始计数,加两个
                    else
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex - 1);
                    }
                }
                //中间行
                if (currentCellIndex / width > 0 && currentCellIndex / width < height - 1)
                {
                    //偶行,0开始计数,加五个
                    if (row % 2 == 0)
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex - width - 1);
                        cellsForOpenContainer.Add(currentCellIndex - 1);
                        cellsForOpenContainer.Add(currentCellIndex + width);
                        cellsForOpenContainer.Add(currentCellIndex + width - 1);
                    }
                    //奇行,0开始计数,加三个
                    else
                    {
                        cellsForOpenContainer.Add(currentCellIndex - width);
                        cellsForOpenContainer.Add(currentCellIndex - 1);
                        cellsForOpenContainer.Add(currentCellIndex + width);
                    }
                }
            }
            //中间列
            if (currentCellIndex % width < width - 1 && currentCellIndex % width > 0)
            {
                //底行,加四个
                if (currentCellIndex / width == 0)
                {
                    cellsForOpenContainer.Add(currentCellIndex + width);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex + width - 1);
                }
                //顶行,加四个
                if (currentCellIndex / width == height - 1)
                {
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex - width + (int)Math.Pow(-1, row + 1));
                    cellsForOpenContainer.Add(currentCellIndex - width);
                }
                //中间行,加六个
                if (currentCellIndex / width > 0 && currentCellIndex / width < height - 1)
                {
                    cellsForOpenContainer.Add(currentCellIndex + width + (int)Math.Pow(-1, row + 1));
                    cellsForOpenContainer.Add(currentCellIndex + width);
                    cellsForOpenContainer.Add(currentCellIndex + 1);
                    cellsForOpenContainer.Add(currentCellIndex - 1);
                    cellsForOpenContainer.Add(currentCellIndex - width + (int)Math.Pow(-1, row + 1));
                    cellsForOpenContainer.Add(currentCellIndex - width);
                }
            }
            //判断容器中所有的点是否是可以添加的点,是就添加到开放列表中,全部判断完清空容器
            for (int i = 0; i < cellsForOpenContainer.Count; i++)
            {
                //关闭列表和不允许通过的地型都不考虑
                if (cellsForAll[cellsForOpenContainer[i]].isEnable == false || cellsForClose.Contains(cellsForOpenContainer[i]))
                    continue;
                int currentGValue = GetCurrentGValue(cellsForOpenContainer[i]);
                if (!cellsForOpen.Contains(cellsForOpenContainer[i]))
                {
                    cellsForOpen.Add(cellsForOpenContainer[i]);
                    cellsForAll[cellsForOpenContainer[i]].hexCellFather = cellsForAll[currentCellIndex];
                    cellsForAll[cellsForOpenContainer[i]].gValue = currentGValue;
                    continue;
                }
                if (cellsForOpen.Contains(cellsForOpenContainer[i]) && cellsForAll[cellsForOpenContainer[i]].gValue <= GetCurrentGValue(cellsForOpenContainer[i]))
                    continue;
                if (cellsForOpen.Contains(cellsForOpenContainer[i]) && cellsForAll[cellsForOpenContainer[i]].gValue > GetCurrentGValue(cellsForOpenContainer[i]))
                {
                    cellsForOpen.Add(cellsForOpenContainer[i]);
                    cellsForAll[cellsForOpenContainer[i]].hexCellFather = cellsForAll[currentCellIndex];
                    cellsForAll[cellsForOpenContainer[i]].gValue = GetGValue(cellsForOpenContainer[i]);
                    continue;
                }
            }
            cellsForOpenContainer.Clear();
        }
    
        /// <summary>
        /// 计算cellsForALL列表中某个点的gValue并且返回
        /// </summary>
        /// <param name="i">该点在列表中的序号</param>
        private int GetGValue(int i)
        {
            int gValue = 0;
            HexCell cellContainer = cellsForAll[i];
            while (cellContainer.hexCellFather != null)
            {
                gValue += cellContainer.mapAssessValue;
                cellContainer = cellContainer.hexCellFather;
            }
            return gValue;
        }
        /// <summary>
        /// 假设列表下标为i的点的父节点为当前点,计算出此时的GValue并且不改变该点的父节点
        /// </summary>
        /// <param name="i"></param>
        private int GetCurrentGValue(int i)
        {
            int gValue = 0;
            HexCell cellContainer = cellsForAll[i];
            gValue += cellContainer.mapAssessValue;
            cellContainer = cellsForAll[currentCellIndex];
            while (cellContainer.hexCellFather != null)
            {
                gValue += cellContainer.mapAssessValue;
                cellContainer = cellContainer.hexCellFather;
            }
            return gValue;
        }
    }
    

    我在添加一个地格四周的地格时使用的是笨办法,有经验的读者可以自行优化(比如直接获得四周所有的地格,但如果是NULL就剔除什么的),由于六边形地图每次移动和计算的量并不大,我就不做了。

    然后是我地格的类HexCell类,这个类大家看看就好,有一些写得不够好的地方请轻喷,本人还是个萌新。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public enum CellTypeForTown
    {
        townCenter, //城镇中心
        townCell,   //城镇普通地格
        normalCell,  //野外地格
        buildCell   //已经建有建筑物的地格
    }
    
    public class HexCell : MonoBehaviour
    {
        public CellTypeForTown cellTypeForTown = CellTypeForTown.normalCell;
        private Town town;
        public HexCoordinates coordinates;
        /// <summary>
        /// 父方格,用于A星寻路
        /// </summary>
        //[System.NonSerialized]
        public HexCell hexCellFather;
        public Color color;
        /// <summary>
        /// 地型评估值,表示到达该地需要付出的地形惩罚,负数表示越走行走值越多;
        /// 比如A点到B点,根据B点地型计算惩罚
        /// </summary>
        public int mapAssessValue = 1;
        public bool isEnable = true;
        /// <summary>
        /// 用于ASTAR寻路
        /// </summary>
        public int fValue = 0;
        public int gValue = 0;
        public void SetTownForCell(Town town)
        {
            this.town = town;
        }
        public Town GetTownForCell()
        {
            return this.town;
        }
        public static HexCell FindCellByCoordinates(HexCell[] cells, HexCoordinates coordinates)
        {
            int row = coordinates.Z * Global.instance.width;
            int colum = coordinates.X + coordinates.Z / 2;
            if (colum < 0 || colum > Global.instance.width - 1)
                return null;
            if (row + colum >= 0 && row + colum < cells.Length)
                return cells[row + colum];
            return null;
        }
        public static HexCell FindCellByCoordinates(HexCoordinates coordinates)
        {
            HexCell[] cells = Global.instance.cells;
            int row = coordinates.Z * Global.instance.width;
            int colum = coordinates.X + coordinates.Z / 2;
            if (colum < 0 || colum > Global.instance.width - 1)
                return null;
            if (row + colum >= 0 && row + colum < cells.Length)
                return cells[row + colum];
            return null;
        }
        /// <summary>
        /// 返回-1表示数组越界
        /// </summary>
        public static int GetCellIndexByCoordinates(HexCell[] cells, HexCoordinates coordinates)
        {
            int row = coordinates.Z * Global.instance.width;
            int colum = coordinates.X + coordinates.Z / 2;
            if (colum < 0 || colum > Global.instance.width - 1)
                return -1;
            if (row + colum >= 0 && row + colum < cells.Length)
                return row + colum;
            return -1;
        }
        /// <summary>
        /// 返回-1表示数组越界
        /// </summary>
        public static int GetCellIndexByCoordinates(HexCoordinates coordinates)
        {
            HexCell[] cells = Global.instance.cells;
            int row = coordinates.Z * Global.instance.width;
            int colum = coordinates.X + coordinates.Z / 2;
            if (colum < 0 || colum > Global.instance.width - 1)
                return -1;
            if (row + colum >= 0 && row + colum < cells.Length)
                return row + colum;
            return -1;
        }
        /// <summary>
        /// 根据一个基础cell和附加坐标,得到基础cell坐标+附加坐标的cell对象;如果数组越界,就返回Null
        /// </summary>
        public static HexCell GetCellByAddCoordinatesVector(HexCell[] cells, HexCell basicCell, HexCoordinates addCoordinates)
        {
            HexCoordinates mHexCoordinates = basicCell.coordinates + addCoordinates;
            return FindCellByCoordinates(cells, mHexCoordinates);
        }
    
        public static List<HexCell> GetCellsAroundCentetByDistance(HexCell[] cells, HexCell centerCell, int distance)
        {
            List<HexCell> townCells = new List<HexCell>();
            int count = distance * distance * 3 + distance * 3 + 1;
            HexCell[] mCells = new HexCell[count];
            int i = 0;
            for (int z = -distance; z <= distance; z++)
                for (int x = -distance; x <= distance; x++)
                {
                    int y = -z - x;
                    if (y < -distance || y > distance)
                        continue;
                    mCells[i] = HexCell.GetCellByAddCoordinatesVector(Global.instance.cells, centerCell, new HexCoordinates(x, z));
                    i++;
                }
            for (i = 0; i < count; i++)
            {
                if (mCells[i] != null)
                {
                    townCells.Add(mCells[i]);
                }
            }
            return townCells;
        }
        public bool CanSetEntityObjToCell(GameObject obj)
        {
            return CanSetEntityObjToCell(obj.transform);
        }
        public bool CanSetEntityObjToCell(Transform obj)
        {
            return CanSetEntityObjToCell(obj.tag);
        }
        public bool CanSetEntityObjToCell(string objTagName)
        {
            if (objTagName == "Untagged")
                return true;
            Transform[] sons = transform.GetComponentsInChildren<Transform>();
            for (int i = 0; i < sons.Length; i++)
            {
                if (sons[i].CompareTag(objTagName))
                    return false;
            }
            return true;
        }
    }
    


    展开全文
  • 在我之前的文章《Unity3D游戏开发之小地图的实现》一文中,我为大家讲解了基于OnGUI()方法绘制贴图实现小地图的方法。那么,今天呢,博主再来为大家分享一种实现小地图的方法。在正式开始今天的文章之前,我们先来...
  • 最近项目中涉及到使用Unity3D来进行地图上国家的渲染,比如把中国圈起来染成红色的这样的需求。 Unity3D把区域渲染是用的MeshRender,关于MeshRender的用法我就不详细讲解了。 最终问题卡在一个点上,对于中国边界...
  • Unity3d A star寻路算法

    2018-07-17 15:15:08
    基于Unity3d的A star寻路算法 ,完整demo 基于unity5.6 ,可以设置地图宽高,物体运行速度,是否可以穿过斜对角障碍。
  • 本书共分为14章,详细讲解了Unity3D的安装、发布、界面等主要功能,并深入介绍AR(增强现实)、VR(虚拟现实)开发方法,以及地图定位、摄像机、声音播放等开发技巧,让读者了解到如何使用Unity3D制作AR\VR产品,...
  • 1.地图 2.敌人的生成和移动 目前利用不同颜色的球体代替不同的敌人,敌人会自动从出生点移动到目标点。不同敌人各种属性不同(生命,速度等) 3.控制游戏视野 可以通过鼠标的滑轮和键盘的wasd键孔氏游戏视野的大小...
  • Unity3D合并着色器

    2015-08-07 12:35:00
    unity 3d倒每次模型更多的是一种着色器。我可以拥有这些车型共享的地图想分享一个着色器。所以每次删除,然后附加,很麻烦。如何才能合并这些着色器? 采纳TexturePacking对 1、遍历gameobject。取出material。而...
  • 新手《Unity3D平台AR开发快速上手–基于EasyAR4.0》上市了,现在京东和淘宝都有卖。书分为2个部分,第一部分是EasyAR4.0基础内容和使用,第二部分是利用EasyAR的稀疏空间地图做室内导航的例子。 这本书的运气不错,...
  • 最早开始是有全景图片,比较早的应用场景在照片拍摄,地图展示上。数据采集需要一台全景摄像机,放到汽车的顶部。开动汽车,慢速驾驶,就可以采集周边建筑的全景图片。数据的成本相对3d建模会低很多。广泛用在gis...
  • Unity3D基础学习之打砖块

    千次阅读 2018-03-26 00:46:22
    Unity3D基础学习之打砖块基于unity20171) 使用Plane创建初始地图(层级菜单[Hierarcy]-> 3D Object -> Plane) 2) 将Plane命名为Gound3) 更改Scalex = 2,y = 2,z = 2,将Plane变为原来的两倍 4) 在Assest下新建一个...
  • 一、在地图上建造炮台并攻击敌人 首先通过点击选择炮台的UI界面选中炮台,然后点击地图中相应方块建造炮台,炮台会自动攻击进入炮台攻击范围内的敌人 二、一些细节上简单的动画特效及粒子特效 1.金钱不足时的闪烁...
  • Unity3D游戏开发之角色控制效果

    千次阅读 2014-05-11 16:51:09
    在仙剑奇侠传四中,玩家可以通过鼠标右键来旋转场景(水平方向),按下前进键时角色将向着朝前(Forward)的方向运动,按下后退键时角色将向着朝后(Backword)的方向运动、当...我们今天要做的就是基于Unity3D来做这样一个角
  • RTS Engine(Unity 3D)——学习笔记(二)三、开始二、GameManager 三、开始   根据该项目的文档,较为简单的游戏开始模式有两种,分别是配置新地图和单人游戏模式,结果分别如下:   由于第一种模式需要...
  • 这篇文章的应用场景是这样子的: ...图片摘自wuyt2008的博客:《unity3d 尝试 基于地理定位的 增强现实》  本文要解决的问题就是,如何判断这些Point的东南西北,即坐标。  博主采用的开发...
  • 对于AI,我的初始想法非常easy,首先他要能动,而且是在地图里面动。 懂得撞墙后转弯,然后懂得射击,其它的没有了,基于这个想法,我首先创建了一个MyTank类,用于管理玩家的坦克的活动,然后创建AITank类,AITank...
  • ◆ 借助于所提供的2D和3D内容,你将学会评估和处理项目进度中来自基于字节大小的片段的挑战,从而获得在交互设计方面解决问题的技能。 在本书的结尾,你将能够灵活使用Unity 3D游戏引擎,并了解利用自己的资源的必要...
  • 像是前一阵《宝可梦:剑/盾》尚未发行时,有国外高玩利用虚幻4引擎复刻初代《精灵宝可梦:火红》并制作出demo,全3D化的地图设计和更改为即时战斗模式的玩法像是打开了宝可梦新创意的大门,实机演示视频放出后立即...
  • 一款基于unity3D的基础迷宫小游戏,可实现双人联机,我们这款迷宫之旅小游戏是一款基于unity 3D的探索休闲类小游戏,可以单人游戏,同时通过主机端和客户端连接一样可以实现双人对战,游戏中玩家预制角色是一个小球...
  • 基于geoserver的伪三维地图制作

    万次阅读 2016-03-29 19:36:17
    小伙伴在用百度高德这类地图的时候有木有发现...基于Unity3D这类开源的三维引擎做的?NONONO,这是真三维地图。笔者的原则就是能用开源软件就绝不会用商业软件。由于现在主流的制作web地图的开源软件是geoserver+open
  • 入门unity开发笔记

    2019-12-20 21:04:34
    刚入门unity3D学习,今天进行我的第一个项目的开发,首先是对项目的策划。 1.游戏玩法大约是冒险的玩法,类似于马里奥,但是这是基于3D视角进行开发的。收集星星,来进行游戏。 2 .游戏素材的收集,对于素材的要求:...
  • Unity3d MapMagic World Generator基于节点的程序和无限游戏地图生成器,图形上的每个节点表示地形或对象生成器:噪声,voronoi,混合,曲线,侵蚀,散射,森林等生态系统,一旦节点连接,魔法发生:游戏地图将创建...
  • 深入讲解:在Unity中使用多个相机 - 及其重要性 探寻 Unity Camera 属性之 Clear Flags 制作大型MMO项目中的相机视角操作【工程】 ... Unity 基于Cinemachine计算透视摄像机在地图中的移动范围 ...

空空如也

1 2 3
收藏数 52
精华内容 20
关键字:

unity3d 基于地图