Unity3D中Isometric Tilemap功能实践
前言
最近出于兴趣想自己做一个2D的游戏,因为有着C#的基础,所以决定使用Unity3D来做。
之前对于Unity3D其实了解不多,不过看了一些Unity3D的视频和官方文档后,暂时做起来也没遇到什么太大的困难。
本篇博客要说的是Unity 2018.3新增的一个东西——Isometric TileMap,一般用于做一个2.5D的地图。
这个东西官方文档讲的并不详细,并且有些配置完全没有说出来,导致始终无法达到预期效果。
国内的各种中文社区和问答网站都没有这方面的资料,最后还是在Unity的英文社区找到了一篇答案才有了进展:参考链接。
但是即使按照这篇答案中的方法进行操作,在我这里依然没法成功实现这个2.5D的地图。
后来自己慢慢摸索才最终实现,所以特此记录下实现的步骤。
导入图片生成纹理图片
如果将使用TileMap画地图比作给墙贴瓷砖,那么首先我们需要为瓷砖设置不同的花纹,所以我们要导入一张图片作为花纹。
导入图片生成纹理图片后,需要将其纹理类型设置为Sprite (2D and UI),因为Tilemaps不支持其它的纹理类型。
注意到纹理属性中的Pixels Per Unit (PPU),它的值默认为100。
这个属性很关键,它决定了这个纹理图片在Unity中显示时,1个Unity的单元显示多少个像素。
也就是说一张400 X 200的纹理图片在Unity中,相当于4*2个Unity单元。
新建瓷砖
纹理就是一个花纹,不可能将花纹直接花在墙上,我们需要根据花纹生成不同的瓷砖,然后再将瓷砖贴到墙上,Tile就是我们的瓷砖。
通过Assets > Create > Tile生成一个Tile文件,然后将之前导入的纹理图片与Tile文件关联。
新建Isometric Tilemap
要贴瓷砖还需要一面墙,而Isometric Tilemap就是我们的墙。
使用GameObject > 2D Object > Tilemap,创建一个带有一个Tilemap子节点的Grid对象。
在这个Grid对象的属性Cell Layout中,我们发现关于Isometric Tilemap有两个选项,一个是Isometric,而另外一个是Isometric Z As Y。
Isometric实现的是相当于一个地形一样的东西,但是想要在这个地形上放上房子和树木之类的,那么需要设置为Isometric Z As Y。
在这里我们看到还有一个Cell Size的设置,我在这里设置为 X:1,Y:0.5,Z:1。(请注意,这里的Z的大小务必为1,否则同样无法在地形上放置房子)
Cell Size中的X为1,表示一个Unity的单元格中X的长度相当于多少个Unity单元。
导入一张400 X 200的纹理图片,它的PPU为100,那么相当于需要4 X 2的Unity单元。
因为我们这里讲CellSize的X与Y设置为1和0.5,所以这张纹理图片在TileMap中的显示占4个单元格。
而对于Grid下的Tilemap对象,我们只需要修改一个属性,即将Tilemap Render的Mode改为Individual。
这么做的原因是只有在Individual下,Scene视图中Tilemap的各个Tile间才能正确排序。
如果是Chunk模式,不同的Tile在绘制时会出现下面这种遮挡的现象:
不过在我们打包时,还是需要将Mode改为Chunk,因为Chunk会按位置对Tiles进行分组,并将它们的Sprite一起批处理以进行渲染,这样会提高性能。
另外在Chunk模式下,还需要将不同的Sprite放到一个Sprite Altas中,这样它们才能正确排序。
因为这篇博客的主题不是这方面所以只是捎带提起,具体如何使用Chunk模式可以查询官方文档,这里不再赘述,先将Mode设置为Individual即可。
新建Tile Palette
有了瓷砖和墙,那么我们还需要一个装瓷砖的箱子。
这个瓷砖箱装着各种各样的瓷砖,当我们贴瓷砖时,就从这个瓷砖箱中取出来用。
Tile Palette就是我们瓷砖箱。
使用Window > 2D > Tile Palette,打开Tile Palette视图。
点击Create New Palette创建一个Tile Palette,请保证这个Tile Palette的属性和Isometric Tilemap的属性匹配,即:
- Cell Size为Manuel,值为 X:1,Y:0.5,Z:1
- Grid为Isometric Z As Y
如果你的图片是矩形图片那么就是,那么这里的Y为0.5,如果基于等距投射的图片,那么Y为0.57735。
创建了Tile Palette后,我们将之前导入的Tile文件拖动到Tile Palette上,也就相当于将瓷砖放到了瓷砖箱中。
如果拖动纹理图片到Tile Palette上,也会自动生成一个Tile文件,这样方便得多。
开始绘制Tilemap
贴瓷砖就是从瓷砖箱中选择瓷砖,然后贴到墙上。
而绘制地图,就是在Tile Palette中选择不同的Tile,然后选定Active Tilemap为指定的TileMap后就可以绘制了。
但是当我们准备画图的时候发现,一个Unity单元格实在太小了,就相当于一个像素那么大。
这里可以通过设置TileMap对象的scale,将其X和Y放大100倍来处理。(当然也可以通过同时调节Grid的Cell Size的X为100,Y为50,然后再将图片的PPU从100改为1)
此时可以看到我们的Tile大小正好合适。
那么我们可以在两个单元格内绘制不同的Tile,但是这里注意到,Tile之间的遮挡存在问题。
解决Tile间的遮挡问题
上面Tile间的遮挡问题,我通过之前提到的Unity英文社区的参考链接解决了。
操作就是通过Edit > Settings > Graphics,修改Transparency Sort Mode为Custom Axis,并将其值设为X:0,Y:1,Z:-0.49。
不同Z Position下Tile的绘制
上面我们实现了基本地形的绘制,现在我们需要在地形上面绘制房子。
之前我们绘制Tile时,Tile Palette的Z Position为0。
现在我们需要在地形上绘制房子,那么就需要调高Z Position,将Z Position设为1。
绘制后发现遮挡顺序不对,咱们的Z Position为1的房子竟然被Z Position为0的地形给遮挡了。
到这里参考之前的帖子也没办法处理这个事,没有任何文档和资料有关于这个事情的处理。
我这里也纠结了很久,搞了一两个晚上都没搞出来,最后直接加了几个QQ群,把问题甩在那里,然后打Dota2去了。
而果然指望别人也不怎么靠谱,结果最后还是自己去研究。
虽然不清楚内部工作原理,但是按照排除法去想了一下相关的几个设置点,问题应该就是出现在透明度排序那里。
于是调节XYZ这三个值,发现将Z进一步调小到-26后就没有问题了,虽然不知道发生了什么,但是终究是搞定了。
以下是最终效果:
总结
不知道为什么最后一个那么大的坑在官方文档上完全没有提及,而且这个功能从这个角度来看,不像是完全做完了的样子。
希望我的这篇博客对后来的趟坑者有用吧,当然如果有用也别忘了点个赞。
如文中有谬误,还望不吝赐教。
PS:
自己建了一个QQ群328544641,用于Unity2D技术的学习交流群,里面暂时就我一个人。
如果您对Unity的2D技术有兴趣,可以互相学习交流。
人不在多,只希望进群的人可以得到自己想要的答案,也同样希望您能在了解的情况下给予一些Unity菜鸡帮助,比如身为菜鸡的我。
Unity3D中Isometric Tilemap功能实践的更多相关文章
- Unity3D游戏开发之游戏读/存档功能在Unity3D中的实现
喜欢我的博客请记住我的名字:秦元培,我的博客地址是:http://qinyuanpei.com 转载请注明出处,本文作者:秦元培, 本文出处:http://blog.csdn.net/qinyuanp ...
- 关于Unity3D中的SerialField这个Attribute的功能
首先我们看看效果,以下是源文件的内容: 然后对应的面板: 要注意的地方其实就这里: 可以看出,public默认就可以在面板中进行修改,相应的设为private的isCreateSoldier却不会出现 ...
- Unity3d中使用Lua
对于手机游戏,如果可以在线更新以实现bug修复.新功能添加等等,其好处自不必多说. 通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考 http://docs.unity3d.com/ ...
- Redis在WEB开发中的应用与实践
Redis在WEB开发中的应用与实践 一.Redis概述: Redis是一个功能强大.性能高效的开源数据结构服务器,Redis最典型的应用是NoSQL.但事实上Redis除了作为NoSQL数据库使用之 ...
- 【吐血推荐】简要分析unity3d中剪不断理还乱的yield
在学习unity3d的时候很容易看到下面这个例子: void Start () { StartCoroutine(Destroy()); } IEnumerator Destroy(){ yield ...
- Unity3D中事件函数的运行顺序
Unity3D中脚本的生命周期是依照预先定义好的事件函数的运行流程来演化的,详细流程例如以下: Editor模式下Reset: 当脚本第一次被挂到GameObject上或用户点击Resetbutton ...
- Unity3D中Ragdoll的用法
一.创建Ragdoll 见unity3d组件文档里的Ragdoll Wizard.由于unity3d中的Ragdoll设置的骨骼点名字与3DMAX里人体骨骼命名有些不一样,下图为Unity3 ...
- (转) [教程] Unity3D中角色的动画脚本的编写(一)
ps: 这两天研究unity3d,对动画处理特别迷糊,不知FBX导入以后,接下来应该怎么操作,看到这篇文章,感觉非常好,讲解的很详细. 已有好些天没写什么了,今天想起来该写点东西了.这次我所介绍的内容 ...
- Unity3d中的PlayerPrefs游戏存档API的扩展
功能 在游戏会话中储存和访问游戏存档.这个是持久化数据储存,比如保存游戏记录. 静态函数 DeleteAll Removes all keys and values from the preferen ...
随机推荐
- python 正则表达式中反斜杠(\)的麻烦和陷阱
这里是一点小心得:由于下面两个原因,在正则表达式中使用反斜杠就会产生了一个双重转换的问题. (1).python自身处理字符串时,反斜杠是用于转义字符 (2).正则表达式也使用反斜杠来转义字符 ...
- git多个远程仓库
1. 前言 用GitHub管理自己的开源项目有几年了,最近一年更新得比较多,仓库也越来越多越来越大.有时候感觉GitHub太慢,尤其是最近感觉更为明显,于是萌生了再找个国内类似GitHub的代码托 ...
- python 冒泡、二分查找
冒泡: import random def _sort(_lst): count = 1 while count < len(_lst): for i in range(0, len(_lst) ...
- 2019年Web前端入门的自学路线
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文.本文内容不定期更新. 我前几天写过一篇文章:<裸辞两个月,海投一个月 ...
- [20181225]12CR2 SQL Plan Directives.txt
[20181225]12CR2 SQL Plan Directives.txt --//12C引入SQL PLAN Directives.12cR1版本会造成大量的动态取样,影响性能.许多人把OPTI ...
- mssql sqlserver存储过程专题
MSSQL存储过程简介及创建方式 mssql_DB_存储过程类型简介 MSSQL sql存储过程创建简介及应用举例 MSSQL SQl server 2008 CLR 存储过程创建举例 MSSQL ...
- python3中list列表的一些操作
最近遇到许多List的操作,感觉它是一种很重要的一种基础数据结构,本人掌握的也不是很扎实,这里找了一些列表的操作,常用函数,记录下来,希望对大家有用.如果理解有偏差,欢迎指正,感谢! (1)列表的合并 ...
- Linux 小知识翻译 - 「代理服务器」
这回聊聊「代理服务器」. 在公司里,不通过代理服务器无法连接互联网的,由于代理服务器的原因,有些服务的使用是受到限制的. 有人可能会觉得为什么会存在这种东西?(这里指代理服务器) Proxy本来的意思 ...
- C语言 实现逆置功能
C语言 实现逆置功能 //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 字符串的逆置 方法1:利用数组 #include<stdio.h> ...
- python 线程队列、线程池、全局解释器锁GIL
一.线程队列 队列特性:取一个值少一个,只能取一次,没有值的时候会阻塞,队列满了,也会阻塞 queue队列 :使用import queue,用法与进程Queue一样 queue is especial ...