Unity教程1:如何切割我的图片素材并使用tilemap搭建游戏背景(Pixels Per Unit设置不合适问题)

目录

 素材

如何切割素材

使用tilemap以及笔刷搭建游戏场景

正确的设置Pixel Per Unit

 创建瓦片块

 规则瓦片Rule Tile的使用

 图层层级的设定


 本人使用2D项目来创建游戏场景,使用的Unity版本为2021.1

这是一个记录向的博客,本人结合了麦扣老师的教程使用自己购买的素材进行Unity的再学习,很基础,主要为了防止自己遗忘也希望能帮助到其他人。

感谢麦扣老师能成为我制作游戏的破门人!

M_Studio的个人空间-M_Studio个人主页-哔哩哔哩视频

 由于制作游戏需要了解一些Unity的API,我们需要一定阅读英文基础的能力,不过官方的脚本手册也是有中文翻译的,在这篇博客中,本人跟随项目中的学习中很多时候知其然不知其所以然,为此我会尽量查询官方手册以保标准,当然错误不可避免,还希望读者指出

在这篇博客中,被块引用的是具体概念及解释,如果你不希望看到这些冗杂的系统概念,可以选择性的不看

本人也只是Unity新手,仅跟着教程制作过两个Demo,考虑到自己学习路上的磕磕绊绊,博客不可避免的写得冗杂,还望各位理解。

手册链接在这:Unity User Manual (2019.3) - Unity 手册

 素材

 本人使用的素材是这个

 来源于Fanatical ,已付费

 有需要素材的读者可以经常在这里逛逛,很多非常棒的游戏素材打包打折销售,价格也不贵。

 我不知道付费购买的素材可否分享,但是可以商用,希望有了解的读者可以告知我一下,方便分享一下。

如何切割素材


这是素材包导入到Unity之后的样子

如果作者没有直接进行切割的话,一般素材是这样子的

 

那么也不需要担心,正好就来学习一下图片素材的切割,看到上面画的红圈圈了吗,素材的制作者直接将这个素材的像素大小标注在了图片上,我们可以非常方便的直接切割了。

那么我们先点击选中我们的素材图片

 在Inspector窗口中,我们就可以看见这张图片的具体信息了

当然可能有一些英文苦手不太了解一些组件的意思,所以我能翻译或者查找的都尽量标出来,当然能看懂最好。 不过当语言成为学习的障碍时是非常痛苦的,学习Unity还是需要一些英文功底的。

在官方手册中,Inspector窗口的定义是这样的。

 首先我们点击Sprite Mode,选择Multiple(复数模式)

 

 Sprite Mode意思是当前这个精灵的模式,默认为single(单独的),即一个单独的精灵,因为single模式不能被切割,所以我们将其更改成Multiple(复数模式)

在官方API手册下它的解释如下:

 然后将Pixels Per Unit更改为512,很简单嘛,我们的图片大小是512X512的(注意!设置PPu为512是个错误,之后会提到)

在官方API手册下,Pixels Per Unit意思如下

如果我们使用默认的Pixels Per Unit,也就是100,那么其意思就是unity中的一个距离单位显示图片的100个像素。

 将Fileter Mode更改成Point

 

 个人理解为点缩放,这样子可以保证我们素材缩放的时候不会糊掉

Filter Mode 当该纹理由于3D变换进行拉伸时,它将如何被过滤插值。共有三种选择:

  1. Point 单点插值,纹理将变得块状化(blocky up close);
  2. Bilinear 双线性插值,纹理将变得模糊(blurry up close);
  3. Trilinear 三线性插值,类似Bilinear,但是纹理还会在不同的mip水平之间(between the different mip levels)进行模糊;

压缩选项中选择不压缩

 然后点一下Apply

 然后点击Sprite Editor,也就是精灵编辑器

 在官方手册中,Sprite Editor的解释如下

 此时会弹出来这个界面

点击左上角的Silce(切割)选项卡

更改切割类型为Grid by Cell Size

 

 关于切割类型,官方手册解释如下:

 简而言之,Grid by Cell Size 这个模式允许我们以类似矩阵的方式对图片进行切割

将Pixel Size调整为16,16,虽然我们整个图片的大小为512,但是它并不是均匀的分布于整个图片上,经过调整发现16X16的效果最好

 

 然后点击右上角的apply即可

这样做的主要目的是为了能使用tilemap的这个组件包,可以看到其中部分图片的切割效果并不算好,但是导入到tilemap就不一样了。

 点这个就可以看到切割的效果如何了。

使用tilemap以及笔刷搭建游戏场景

 使用tilemap可以大大减少我们搭建场景的工作量,毕竟谁也不想一个个的拖拽素材图片来构造场景

 还容易摆歪。

那么这个时候就可以使用tilemap来减少工作量了。

在Hierarchy中,点击这个+或者空白处右键可以添加组件,我们找到2DObject->tilemap就可以添加一个tilemap到当前的场景里头了。

 Unity会为我们生成一个Grid(网格),点击Grid就可以看见其划分的网格了

 Grid在官方手册中的解释以及功能介绍如下

 Grid中允许存放多个tilemap

 点击Grid的菜单,就可以看见tilemap在里头,为了方便管理我们可以为其重命名,一个游戏最最基本的场景那就必须先是一个背景了,那么我们为其命名为BackGround

 

然后在Window选项卡下找到2D->tile Palette

 

 

 点击Create New Palette即可创建一个用于存放tilemap的文件夹,这里面存放我们各种瓦片信息

 然后把我们刚才切割过的图片往里拖拽一下即可。

 导入后效果如下

 一些切割的不太好的瓦片是可以删去的

点击Edit

选中橡皮擦

 

 

以上7个工具依次功能为

选择工具,快捷键S

移动工具,快捷键M

画笔工具,快捷键B

方形区域填充工具,快捷键U

吸管工具,取样选中瓦片并绘制,快捷键I

橡皮工具,擦除瓦片,快捷键D

油漆桶工具,快捷键G

 以上的工具不仅能对场景绘制,也可以编辑tilemap内部,比如删去切得不好的瓦片,不过在这里切的都刚刚好,不需要删除

这个选项和绘画软件中的图层是一样的,现在当前我们绘制的图层名字为BackGround

 那么我们尝试画一个?

结果让人哭笑不得,怎么这么小?都快成一个像素点了!

正确的设置Pixel Per Unit

 这个是本人自己折腾素材踩的坑,折腾了一下午,学到了很多

出现这种奇怪的错误肯定是前面出问题了,那么为什么会这么小?

回到素材的参数设置上,其他的设置都不关乎大小,那么罪魁祸首就只有PixelPerUnit(后文简称PPU)了!

不对啊?为什么不是512呢?这张图片不是512X512大小么?

我们回到PPU这个参数的效果上来看,PPU的意思是:unity中的一个距离单位显示图片的PPU个像素。

那么切割时,用了16X16的矩阵进行切割,也就是在我们的主观来看,我们希望每一个距离单位显示16个像素。但是我们设置成了512,被切割的单个瓦片有整整512像素,为了保证能符合PPU,也就是1个单位距离走过512像素,Unity按比例缩小了我们的瓦片,造成了这种情况。

所以我们要把PPU改成16才是正确的。

 总结一下:

为了正确的设置素材的PPU,我们可以先进行矩阵切割,然后再设置好PPU,当然计算也是可行的。

  正常的瓦片

 创建瓦片块

 那么问题来了,创建的瓦片都是一片片的又能怎么样,还不如一个整体不切直接往里塞呢!

那么我们这里就可以用到我们的方块区域选择工具了,我们用它来打包一个瓦片块!在非编辑模式下选中方块区域选择工具

 框选一整块房子的瓦片

 

 点击画笔工具,这个时候在场景内我们就能看见一个打包了的瓦片块了

 规则瓦片Rule Tile的使用

 使用这个功能之前,需要保证你的编辑器有这个软件包,假如你的编辑器版本没有2D Tile Extra

可以到GitHub中下载对应的版本。

GitHub - Unity-Technologies/2d-extras at package_2021.1

在我们自己项目的TileMap文件夹中,右键找到新建一个Rule Tile

 

我们选择其中一个切好的瓦片作为其图标,然后点击Tiling Rules的加号,新建一个瓦片规则

这个是我当前参考的规则瓦片块

 以这个瓦片块,新建几个规则

我们可以看到,当前的这个图块的逻辑是希望在我们的场景之中创建出一条蓝色的道路,为了契合道路边缘的像素曲线,整个块被分为了9份

 被框选的5块和未被框选的4块。

那么,我希望我们的规则瓦片可以非常方便的画出来被雪地包围的蓝色道路,效果如同我已经做好的泥地一样,只需要简单的框选,中心的纯色图块会被其他8个图块有逻辑的包围。

 既然需要其他8个图块,那么我们就新建8个瓦片规则,分别找到被切割好的8个图块。

但是在切割了如此多瓦片的图片里面找还是非常头疼的,所以我们可以为我们将要使用的瓦片重命名,以更好的找到他们。

重新点回我们的切割图片的素材,再次用精灵编辑器打开它,点击选中即可为其改名

 重命名结束后别忘了点击Apply。

那么接下来我们找到这8个图块,准备为其设置逻辑。

我的设置如下

绿箭头代表当前这个图块附件8格检测是否有图块的逻辑,我们已前两个图块为例子进行解释

 第一个图块,我们结合美术作者给出的标准,可以知道它肯定位于中心

 那么也就是只有当它的附近一整圈有图块的时候,才会使用这个图块填充,所以,我们将其填充的规则一圈全部变成绿箭头。

 而第二个图块则是这个位置,那么它的逻辑就是当右边有图块,上面有,下面有而左边是没有图块的时候才填充这个。

 

 同理,其他的图块逻辑也是一样的,如果理解起来有点困难,还请一定要不嫌麻烦自己动手试一试。Unity也会贴心的在调整在底下显示当前逻辑所产生的效果。

 那么创建完了之后,我们把这个Rule Tile拖拽进我们的调色盘,也就是Tile Palate中。

 点击它,选择方形工具,画来试试看!

嗯!很显然它已经满足了我们最基本的框选逻辑,但是还是有4个过渡角没有设置,我们补充一下。也就是这四个

 

 

 完美!

 图层层级的设定

 我们的素材中,还有很多的建筑图块,为此我们需要新建一个图层以及TileMap以防止绘制图块的时候冲突。

 右键我们的Grid,新建一个TileMap,重命名为Building,这个操作就不截图了。

 选中其中的一个,然后为其设置图层

 

 默认只有一个Default图层,我们可以新建一个称为Building

在这里的Oder in Layer以及Sorting Layer,它们都是用来操控图层渲染次序的,当然也可以与显示顺序有关,Sorting Layer控制的是当前的组件所属的大图层,比如Default以及我们刚才创建的Building,而Oder in Layer则是当前这个大图层内部的排序,比如Build图层下会有房子和窗子,我们窗子和房子都在Build这个大图层里,为了防止房子和窗子的贴图互相覆盖,我们可以将窗子的Oder in Layer提升,让其显示在房子前。

然后就可以在调色盘内部切换当前要绘制的Tile Map了!

 这些工作做完后,我们就可以愉快的绘制我们的场景了,我这里简单绘制了一个场景。

 为场景物体添加Tilemap Collider 瓦片碰撞器

 制作场景的本意是为了与操纵的角色发生互动,那么既然我们简单的绘制了场景内的物体,那么就需要为其添加碰撞体,毕竟我们也不希望我们的角色从房子上头穿过去。

绘制时,我将背景雪地与建筑的Tile Map分了个类,背景不需要碰撞体,我们就选择Building的tilemap来进行添加,可以让我们的人物碰到建筑就能停下来。

找到Building的Tile Map,为其添加一个组件,

 在搜索窗口中查找TileMap Collider2D

 

瓦片地图 2D 碰撞体 (Tilemap Collider 2D)

可将 Tilemap Collider 2D 组件添加到 Tilemap 游戏对象来为相应 Tilemap 组件中设置的每个__瓦片 (Tile)__ 生成__碰撞体 (Collider)__ 形状。

在 Tilemap 组件中添加或删除瓦片时,Tilemap Collider 2D 组件会在 LateUpdate 期间更新碰撞体形状。

为 Tilemap 组件中的每个瓦片生成的碰撞体形状取决于瓦片资源中设置的所需碰撞体类型。

 

Material 一种物理材质,可用于确定碰撞的属性(例如摩擦和弹性)。
Is Trigger 选中此复选框可使 Tilemap Collider 2D 组件作为触发器运行。
Used by Composite 选中此复选框可使此碰撞体由附加的 Composite Collider 2D 组件使用。
当启用 Used by Composite 时,除了 Offset 之外的所有属性在 Tilemap Collider 2D 组件中都不再可用。相反,这些属性由附加的 Composite Collider 2D 组件控制。
Used by Effector 选中此复选框可使 Tilemap Collider 2D 组件由附加的 Effectors 2D 组件使用。
Offset Tilemap Collider 2D 几何形状的局部偏移。

为我们的Building Tile Map加入了Tilemap Collider 2D之后,我们可以发现场景内的建筑都有了自己的碰撞体。为了更好的观察,我先将背景关闭。

 但是我们放大来看,虽然说生成的Collider曲线和我们的素材非常契合,但是其内部依旧是一片片的瓦片

 我希望他能变成一个整体,那么在Tilemap Collider 2D中我们可以找到Used By Composite即使用复合。

 我们点击它,Unity会提示我们,想要复合,需要额外添加一个CompositeCollider2D组件

 那么我们添加一个。

2D 复合碰撞体 (Composite Collider 2D)

2D 复合碰撞体组件是用于 2D 物理的碰撞体。与大多数碰撞体不同,此碰撞体没有定义固有的形状。相反,此碰撞体将合并所设置的 2D 盒型碰撞体 (Box Collider 2D)2D 多边形碰撞体 (Polygon Collider 2D) 的形状。

2D 复合碰撞体使用所有此类碰撞体的顶点(几何体),并将这些顶点合并为由 2D 复合碰撞体本身控制的新几何体。

2D 盒型碰撞体和 2D 多边形碰撞体组件具有 Used By Composite 复选框。

勾选此复选框即可将这些碰撞体附加到 2D 复合碰撞体。这些碰撞体还与 2D 复合碰撞体附加到同一 2D 刚体。启用 Used by Composite 时,其他属性会从该组件中消失,因为这些属性现在由附加的 2D 复合碰撞体控制。

Density 通过更改密度可更改游戏对象关联的 2D 刚体的质量计算。如果将该值设置为 0,则其关联的 2D 刚体将在所有质量计算(包括质心计算)中忽略 2D 碰撞体。请注意,只有在关联的 2D 刚体组件中启用 Use Auto Mass 时,此选项才可用。
Material 一种 2D 物理材质,可用于确定碰撞的属性(例如摩擦和弹性)。
Is Trigger 如果希望 2D 复合碰撞体作为触发器运行,请选中此框(请参阅关于碰撞体的概述文档以了解有关触发器的更多信息)。
Used by Effector 如果希望 2D 复合碰撞体由附加的 2D 效应器组件使用,请选中此框。
Offset 设置 2D 碰撞体几何形状的局部偏移。
Geometry Type 合并碰撞体时,所选碰撞体的顶点将组合为两种不同几何体类型之一。使用此下拉选单,可将几何体类型设置为 OutlinesPolygons
    Outlines 生成具有空心轮廓的 2D 碰撞体,与 2D 边界碰撞体 (Edge Collider 2D) 生成的结果一样。
    Polygons 生成具有实心多边形的 2D 碰撞体,与 2D 多边形碰撞体 (Polygon Collider 2D) 生成的结果一样。
Generation Type 该方法用于控制在更改 2D 复合碰撞体时或者更改其任何成员碰撞体时何时生成几何体。
    Synchronous 对 2D 复合碰撞体或其使用的任何碰撞体进行更改时,Unity 立即生成新几何体。
    Manual 仅在手动请求时才生成新几何体。要请求生成几何体,请调用 CompositeCollider2D.GenerateGeometry 脚本 API,或者单击选择项下方显示的 Regenerate Geometry 按钮。
Vertex Distance 设置从复合碰撞体收集的任何顶点允许的最小间距值。比此限值更近的任何顶点都将被删除。此设置可用于控制顶点合成的有效分辨率。
Edge Radius 控制边缘周围的半径,使顶点为圆形。这会产生一个具有圆凸角的更大 2D 碰撞体。此设置的默认值是 0(无半径)。仅当 Geometry Type 设置为 Outlines 时,此设置才有效。

 添加一个CompositeCollider2D组件之后,我们发现,它自动的为我们添加了刚体组件也就是Rigidbody 2D

2D 刚体

2D 刚体组件将对象置于物理引擎的控制之下。标准刚体组件中的许多熟悉概念都延续到了 2D 刚体;不同之处在于,在 2D 中,对象只能在 XY 平面中移动,并且只能在垂直于该平面的轴上旋转。

Body Type 有三个选项;

每个选项定义一种常见和固定的行为。附加到 2D 刚体的 2D 碰撞体将继承 2D 刚体的 Body Type。这三个选项是:

  • Dynamic
  • Dynamic 类型的 2D 刚体设计为在模拟条件下移动。这种刚体类型具有可用的全套属性(例如有限质量和阻力),并受重力和作用力的影响。Dynamic 刚体类型将与每个其他刚体类型碰撞,是最具互动性的刚体类型。这是需要移动的对象的最常见刚体类型,因此是 2D 刚体的默认刚体类型。此外,由于具有动态性并与周围所有对象互动,因此也是性能成本最高的刚体类型。选择此刚体类型时,所有 2D 刚体属性均可用。

    请勿使用变换组件来设置 Dynamic 类型的 2D 刚体的位置或旋转。模拟系统会根据 Dynamic 2D 刚体的速度对该刚体重新定位;可以通过脚本施加于刚体的力来直接更改此值,也可以通过碰撞和重力来间接更改此值。

  • Kinematic
  • Kinematic 类型的 2D 刚体设计为在模拟条件下移动,但是仅在非常明确的用户控制下进行。虽然 Dynamic 2D 刚体受重力和作用力的影响,但 Kinematic 2D 刚体并不会受此影响。因此,Kinematic 2D 刚体的速度很快,与 Dynamic 2D 刚体相比,对系统资源的需求更低。Kinematic 2D 刚体按设计应通过 Rigidbody2D.MovePositionRigidbody2D.MoveRotation 进行显式重定位。应使用物理查询来检测碰撞,并通过脚本确定 2D 刚体应该移动的位置和方式。

    Kinematic 2D 刚体仍然通过速度移动,但是此速度不受作用力和重力的影响。Kinematic 2D 刚体不会与其他 Kinematic 2D 刚体和 Static 2D 刚体碰撞,只会与 Dynamic 2D 刚体碰撞。与 Static 2D 刚体(见下文)相似,__Kinematic__ 2D 刚体在碰撞期间的行为类似于不可移动的对象(就像具有无限质量)。选择此刚体类型时,与质量相关的属性将不可用。

  • Static
  • Static 2D 刚体设计为在模拟条件下完全不动;如果任何对象与 Static 2D 刚体碰撞,此类型刚体的行为类似于不可移动的对象(就像具有无限质量)。此刚体类型也是使用资源最少的刚体类型。Static 刚体只能与 Dynamic 2D 刚体碰撞。不支持两个 Static 2D 刚体进行碰撞,因为这种刚体不是为了移动而设计的。

    此刚体类型只有极其有限的属性集。

Body Type 设置 2D 刚体的组件设置,从而可操纵移动(位置和旋转)行为和 2D 碰撞体交互。
选项为:__DynamicKinematicStatic__
Material 使用此属性可为连接到特定父 2D 刚体的所有 2D 碰撞体指定公共材质。
注意:2D 碰撞体使用自己的 Material 属性(如果已设置)。如果此处或在 2D 碰撞体中未指定材质,则默认选项为 None (Physics Material 2D)。这种情况下使用可在 Physics 2D 窗口中设置的默认材质。
2D 碰撞体使用以下优先级顺序来确定要使用的 Material 设置:
1. 在 2D 碰撞体上指定的 2D 物理材质。
2.在附加的 2D 刚体上指定的 2D 物理材质。
Physics 2D 窗口中指定的 2D 物理材质默认材质。
提示:使用此设置确保附加到同一 Static Body Type 2D 刚体的所有 2D 碰撞体都可使用同一材质。
Simulated 如果希望 2D 刚体以及所有附加的 2D 碰撞体和 2D 关节在运行时与物理模拟系统交互,请启用 Simulated__(选中复选框)。如果禁用此功能(取消选中复选框),这些组件不会与模拟系统进行交互。请参阅下面的 2D 刚体属性:Simulated 以了解更多详细信息。默认情况下会选中此框。 | | Use Full Kinematic Contacts__ 如果希望 Kinematic 2D 刚体与所有 2D 刚体类型碰撞,请启用此设置(选中复选框)。这种情况下类似于 Dynamic 2D 刚体,不同之处在于 Kinematic 2D 刚体在接触另一 2D 刚体组件时不会被物理引擎移动,而会充当一个具有无限质量的不可移动对象。禁用 Use Full Kinematic Contacts 时,__Kinematic__ 2D 刚体只会与 Dynamic 2D 刚体碰撞。请参阅下面的 2D 刚体属性:Use Full Kinematic Contacts 以了解更多详细信息。默认情况下会取消选中此框。
Collision Detection 定义如何检测 2D 碰撞体之间的碰撞。
        Discrete Collision Detection 设置为 Discrete 时,具有 2D 刚体和 2D 碰撞体的游戏对象在物理更新期间可以重叠或穿过彼此(如果移动得足够快)。仅会在新位置生成碰撞触点。
        Continuous Collision Detection 设置为 Continuous 时,具有 2D 刚体和 2D 碰撞体的游戏对象在更新期间不会穿过彼此。相反,Unity 会计算 2D 碰撞体的第一个影响点,并将游戏对象移动到该点。请注意,此设置比 Discrete 耗费更多 CPU 时间。
Sleeping Mode 定义游戏对象如何在处于静止状态时“睡眠”以节省处理器时间。
        Never Sleep 禁用睡眠(应尽可能避免此设置,否则会影响系统资源)。
        Start Awake 游戏对象最初处于唤醒状态。
        Start Asleep 游戏对象最初处于睡眠状态,但可以被碰撞唤醒。
Interpolate 定义如何在物理更新间隔之间插入游戏对象的移动(运动趋于颠簸状态时很有用)。
        None 不应用移动平滑。
        Interpolate 根据游戏对象在先前帧中的位置来平滑移动。
        Extrapolate 根据游戏对象在下一帧中的估计位置来平滑移动。
Constraints 定义对 2D 刚体运动的任何限制。
        Freeze Position 选择性停止 2D 刚体沿世界 x 和 y 轴的移动。
        Freeze Rotation 选择性停止 2D 刚体围绕世界 z 轴的旋转。

在添加了这两个组件之后,记得进行如下操作

 将Body Type 置换为Static

 

 不然我们的建筑会掉出去。


 好了,以上就是关于如何使用TileMap的细致操作过程的记述了!希望对你有点帮助!喜欢可以点个赞支持一下!感谢阅读!

猜你喜欢

转载自blog.csdn.net/m0_53607711/article/details/129442727