| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 游戏开发 -> Unity2D 自定义Scriptable Tiles的理解与使用(三)——开始着手构建一个基于Tile类的自定义tile(上) -> 正文阅读 |
|
[游戏开发]Unity2D 自定义Scriptable Tiles的理解与使用(三)——开始着手构建一个基于Tile类的自定义tile(上) |
本文章使用的为 Unity201Unity版本8.4.36f1,脚本语言为C# 引言:在上篇文章中,我们学习了Tile类的相关知识,了解了继承自Tile类的好处。那么现在,激动人心的时刻终于来了,我们要自己创建一个自定义瓦片了!在这篇文章中,我们将会一步步地实现一个带有简单功能的自定义瓦片。 正文:首先先确定我们的目标,在这个文章中我们的目标是建立一个有如下功能的瓦片: 1.可以根据上下左右相邻的格子状态(有无瓦片)来确定要显示的图片。 (其实这个功能基本就是Pipeline瓦片的功能,而且是RuleTile功能的简化版,之所以要实现这个功能是因为这个功能简单,方便展示) 2.可以附加一个小人模样的游戏对象,并且每个小人的颜色都是随机得到的。 好那开始构建我们的瓦片 首先创建一个脚本资源,我在这里把它命名为MyTile。(other文件夹是和该文章无关的文件夹,直接忽视就好),如下图所示: 然后双击脚本进入脚本编辑界面(我这里用visual studio 2019),如下图所示: 我们先将Start方法和Update方法删掉。 接着我们需要引用UnityEngine.Tilemaps命名空间,这样我们就可以调用和Tilemap相关的API了。接着我不再让这个脚本继承自MonoBehaviour,而是改为继承自Tile,如下图所示: ?好,以上的步骤完成之后,我们先来实现我们想要的第一个功能,这个功能要求要根据上下左右的格子有无瓦片(这个瓦片是专指我创建的Mytile瓦片,其他的任何系统自带瓦片或自定义瓦片不包括在内)来确定瓦片所展现的图像。 以下为功能细节设想: 我们先在任意位置放置一个瓦片,如下为示意图: 这时瓦片上下左右都没有瓦片,?我就想让该瓦片呈现默认图像(竖着的道路)。如果我在这个瓦片右边再放一个瓦片,普通的瓦片会是这样的: ?而我想要的效果显然是这样的,请看gif动图: 应该变为两个横着的道路 要想实现这个功能,首先我们来看看一下整个过程中发生了什么事。 一开始场景中已经有一个方块了,然后我的笔刷接近这个方块,在接近的一瞬间,发生了两件事: 1.笔刷控制的方块的图像改变了(从原来竖着的变为横着的) 2.这个已有的方块的图像也改变了(从原来竖着的变为横着的) 不仅笔刷所在的位置的瓦片图像改变了,它相邻的方块图像也改变了。所以我们不仅要让笔刷位置的瓦片进行刷新,还要让它相邻(上下左右)的瓦片也进行刷新。 还记得这个系列的第一篇文章里写到的RefreshTile方法吗,我们现在应该知道要想实现这个功能,要怎么写这个方法了。 先把这个方法写出来,动手写了”public override“之后,如果是直接选了vs智能提示的选项,就是下图这样的: 动图展示: 这里的 base.RefreshTile(position, tilemap) 是调用父类的被重写方法,父类的被重写方法已经实现了刷新笔刷位置瓦片的功能,所以我们要做的是刷新它上下左右的瓦片。 这里我们要学习一个新的知识。 方法参数中ITilemap类型的参数tilemap可以调用实例方法RefreshTile(Vector3Int position) 这个方法的名字和我们写的瓦片的这个RefreshTile方法是一致的,但是是两个完全不同的方法,它是真正让tilemap刷新我们瓦片的方法。我们写的MyTile类的爷爷类(Tile的父类)是TileBase类,在TileBase类的RefreshTile里就写了一个tilemap.RefreshTile(position)来刷新笔刷所在位置的瓦片。 以下是官方对这个方法的介绍: ITilemap.RefreshTileDeclarationpublic void?RefreshTile(Vector3Int?position); Parameters
DescriptionRefreshes a Tile at the given XYZ coordinates of a cell in the :Tilemap.翻译:刷新用xyz坐标指定位置的Tilemap格子上的瓦片。 The?Tilemap?will retrieve the rendering data, animation data and other data for the?Tile?and update all relevant components. 翻译:Tilemap将检索Tile的渲染数据、动画数据和其他数据,并更新所有相关组件。 那我们就可以开始利用这个方法刷新周围位置瓦片了,只需要上下左右四个位置刷新一遍就行。瓦片的RefreshTile方法里的参数position指代了我们当前笔刷的位置。所以我们就可以写出如下图所示的代码来: ?怎么样,是不是很简单,只需要多写四行代码就行。可以在下面复制代码:
好那我们现在解决了刷新的问题。但是这个功能仍然不能运行,因为还有一个最核心的工作没有做,那就是给予tilemap正确的图片用以显示。 回忆一下第一篇讲的哪个方法是用来让tilemap获取自定义瓦片渲染信息的 答案是GetTileData方法。 我们先将这个方法写出来,如下图所示: ?这个方法可以将笔刷所在位置的瓦片渲染信息交给tilemap,让tilemap可以正确地渲染出我们的瓦片。 我们在类体里写一个Spirte[]数组类型的成员变量sprites。用来存放所有可能显示的图片。 ?现在我们在GetTileData方法里面写三行代码,如下图: ?这里我们先写了一个int类型的变量来表示该瓦片应该显示的图片的编号,再通过我们自己编写的方法getIndex获取到瓦片应该显示的图片编号,最后根据编号在sprites里找到对应的图片赋值给参数tileData里成员变量的sprite。 好,现在我们来写getIndex方法。如下列代码:
首先写一个String类型变量roadSituation来表示瓦片周围的情况(默认为空字符串)。 然后判断左边相邻位置有没有瓦片:
看看这行代码,这里又引入一个新方法:tilemap.GetTile(Vector3Int position) 这个方法可以得到该tilemap指定位置的瓦片,得到的实例就是我们写的MyTile脚本的实例,如同所有ScriptableObject一样,不了解ScritableObject的朋友可以先去了解一下,就明白什么意思了。所以检测的是有没有MyTile瓦片,而不是检测所有瓦片。 如果等于this,即这个实例本身,那就说明左边是有瓦片的,那就让roadSituation加上“a”表示左侧有瓦片。
下面的几行代码都是同样原理,右边有瓦片就加“b”,上面有加“c”,下面有加“d”。这时的
roadSituation就表示了周围的真实情况,例如它的值为“a”就表示只有左侧有瓦片,为“ab”表示左右有瓦片而上下没有,“abcd”就表示上下左右都有瓦片。 接着就是根据roadSituation的值来返回一个指定的编号了。
若周围没有任何瓦片,即roadSituation的值为 ""(空字符串),就返回0(默认值)。 其实我们要先确定好sprites图片数组的各个下标对应的图片,我这里采用的方案是这样的 这样sprites[0]就是编号为0的图片,sprites[8]就是编号为8的图片,等会在Inspector中就用这个顺序放图片。 例如情况是“ac”的话(左边和上边有瓦片),返回的就是2 GetTileData方法里面的index变量就会被赋值为2,就表示选择sprites[2]也就是这里的编号为2的图片,刚好是这张连接上面和左面的图片。然后将图片赋值给tileData.sprite。 好,现在我们已经把第一个功能的代码部分基本搞定了,我们可以测试一下了。但这时我们发现,这个脚本是绑定不了任何游戏对象的,这是因为该脚本继承自TileBase,而TileBase又继承自ScriptableObject。ScriptableObject是不能绑定在任何游戏对象上的,而是要通过创建资产(Asset)的方式创建,我们需要在我们的MyTile上面加上一行代码。如下图所示: ?这行代码的意义就是创建一个资产菜单,并命名为"MytTile"。 现在,我们可以通过在资产框中按右键创建一个MyTile类型的瓦片资产啦! 如下面动图所示:? 给这个瓦片起一个有意义或你喜欢的名字,然后点击我们的瓦片资产,在右边选择Inspctor窗口。 会出现这样的界面。 ?展开Sprites,在size处输入11,建立一个容量为11的图片数组。 ?按照约定好的图片顺序放入我们的图片,图片顺序如下图: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 按照顺序放图片 那么我们的第一个功能算是彻底做完啦! 来测试一下! 没毛病! 以下是MyTile类目前的所有代码,只实现了第一个功能。
那这篇文章我们先实现第一个功能,第二个功能我将在下一篇文章中一步步地实现。 谢谢大家观看,希望这篇文章对大家学习有帮助,有什么建议或意见可以打在评论区噢 :) |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/17 3:05:29- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |