Unity3D仿星露谷物语开发9之创建农场Scene
1、目标
绘制农场的场景。通过不同Sorting Layer控制物体的显示优先级,绘制Tilemap地图,添加Tilemap Collider碰撞器,同时添加Composite Collider碰撞器优化性能。
ps:绘制Tilemap的技巧:通过"Shift + [" 可以左右翻转Tile,通过"]"可以旋转Tile。
2、创建新Scene
点击【File -> New Scene】,创建新的场景命名为Scene1_Farm。
将该Scene保存到Assets -> Scenes下。现在该目录下有2个Scene,其中PersistentScene保存游戏的核心逻辑,该逻辑不会因为场景切换而消失。
现在,我们需要这两个场景同时存在。此时,点击PersistentScene,然后右击Scene1_Farm选择“Open Scene Additive”,以附加的形式打开第2个场景。
添加完成后,我们看到Hierarchy中同时存在了2个Scene。
在Hierarchy中右击Scene1_Farm,点击“Set Active Scene”。虽然同时存在两个场景,但是只能有一个激活场景。
3、创建Tilemap Grid
(1)Tilemap的概念
Tilemap是Unity中用于绘制2D地图的核心工具。它允许开发者以瓦片(Tile)为单位,快速构建出复杂的地图场景。以下是Tilemap基础绘制步骤:
1)创建Tilemap
在Unity的层级窗口中,依次点击“Create”->“2D Object”->“Tilemap”,这将自动创建包含Grid和Tilemap两个GameObject对象的结构。Grid对象负责定义网格属性,而Tilemap对象则用于绘制瓦片。
2)配置调色板(Palette)
打开调色板窗口(Window->Tile Palette),并创建一个新的调色板。将所需的精灵(Sprite)拖动到调色板中,以生成对应的瓦片。这些瓦片将用于后续的地图绘制。
3)绘制地图
选择调色板中的瓦片,并使用笔刷(Brush)工具将其绘制到Tilemap上。通过调整笔刷的大小和形状,可以绘制出线条、方块等各种形状。
4)添加碰撞体
为了让角色能够在地图上移动并触发碰撞事件,需要给Tilemap对象添加一个Tilemap Collider 2D组件。此外,还可以通过Composite Collider来优化碰撞体的生成,以减少不必要的性能开销。
(2)Tilemap创建示例
删除Scene1_Farm中的Main Camera。
右击Scene_Farm,点击GameObject -> 2D Object -> Tilemap -> Rectangular。
创建完毕后,重新命名如下所示:
为了绘制有层次感的地图,我们需要绘制多个Tilemap,对应不同的Sorting Layer。这样做的好处是:比如可以在第一层放置草,第二层放置花,这样花不会遮挡草,更有层次感。
所有的层级关系如下:
通过复制Tilemap类型的Ground1,我们得到如下9个Tilemap:
(3)创建Sorting Layer
给每个Tilemap创建对应的Sorting Layer,Sorting Layer的排序也是一致的。
调整每个Tilemap对应的Sorting Layer值。
(4)创建GridProperties
假如我们希望在Tilemap中绘制出玩家在种植作物时可以挖掘的东西,可以通过Tilemap来绘制这些信息,但是对玩家是不显示的,需要使用代码来检索他们。
所以在Tilemap Grid中,右击创建一个空的游戏对象命名为GridProperties。在这个对象下,我们将创建一些隐藏的Tilemap。
其中Boolxxx都是tilemap类型的。
设置所有Boolxxx的Tilemap的Sorting Layer为Collisions。
暂时设置GridProperties为非Active,我们在后面教程中再使用该功能。
(5)保存Tilemap Grid为预设体
在Assets -> Prefabs下创建Maps目录,并将Tilemap Grid拖入到该目录下生成预设体。
接着,解除Tilemap Grid与预设体的关联,右击 -> Prefab -> Unpack Completely。如果Tilemap Grid与预设体有关联,将大大减慢速度。
4、绘制Tilemap地图
(1)准备工作
在Assets -> Tilemap下创建Tiles和Tile Palettes两个目录。
其中Tile Palettes存放外部导入的瓦片图片,Tiles存放瓦片数据。
打开Tile Palette面板,位于【Window -> 2D -> Tile Palette】。
(2)创建GroundTileSet
在Assets -> Tilemap -> Tiles下再创建子目录GroundTileSet。
在Tile Palette面板下新建一个Palette命名为GroundTileSet。
点击Create之后,保存到Assets -> Tilemap -> Tile Palettes目录下。
将Assets -> Sprites -> Tile Sprites下的GroundTileSet拖入Tile Palette如下:
拖入后提示保存位置时,选择Assets -> Tilemap -> Tiles -> GroundTileSet目录。
选中Assets -> Tilemap -> Tiles -> GroundTileSet下生成的所有Tile,切换到Inspector面板,设置Collider Type为None。我们不希望这些Ground类型的Tile与物理系统发生交互。
(3)通过Bush绘图
1)选择Coordinate Brush
在Tile Palette面板中选择Coordinate Brush,该Brush会在绘画时实时显示坐标的信息。
第一个选项的值“Ground1”对应Hierarchy -> Scene1_Farm -> Tilemap Grid中的Ground1,后续手工绘制时创建的tiles都属于Hierarchy -> Scene1_Farm -> Tilemap Grid -> Ground1对象。
2)创建地图4个顶点
现在我们要创建80*60的地图,所以X方向是40,Y方向是30,两个方向都是从0开始的。
我们选择一个Tile,分别放到(40,30,0),(-40,30,0),(40,-30,0),(-40,-30,0)。
以上4个点确定了农场的大小。
3)使用Pick进行复制
我们拖动Tile创建一条边如下:
然后使用Tile Palette中的Pick工具选择这条边进行快速的复制。
处理完之后效果如下:
目前草地上草的图案一模一样有点假,需要选择其他几种草的Tile随机点缀在某一块区域,然后在将该区域复制到整个草坪上。这样整个草坪都是各种各样的草图案。
如上面的草坪,就不会单一了。
4)绘制路面
绘制的路面如下图土灰色部分。
5)路面镶边
6)在Ground2上种花
7)在Ground3放石块和篱笆
石块的分布点如下:
创建篱笆后整体效果如下:
角色散步的画面如下:
5、创建农舍
(1)导入Tilemap
创建新的Palette
存储到Assets -> Tilemap -> Tile Palettes下:
将Sprites Textures -> Buildings下的Farmhouse 拖入到Tile Palette,并将tilemap存到Assets -> Tilemap -> Tiles -> Buildings。
设置所有的Tiles的Collider Type为None.
(2)绘图
为了形成深度的错觉,房子会切分成两部分绘制,上部分的显示层级高于人,下部分的显示层级低于人。这样人可以走到屋子的前面,只能走到屋顶的后面。
这部分选择Ground2.
这部分选择Front1。
在Scene中重新组装后如下:
6、添加碰撞
(1)导入Tile
目前房子、围栏、石块等人都是可以穿过去的,这个是不正确的,需要在一些物体上添加碰撞体,这样人就不用穿透过去了。
创建新的Pallete名为"Custom Tiles",并保存到Assets -> Tilemap -> Tile Palettes下。
把”Collision Tile Diagonal / CollisionTile / HalfCollisionTile"三个拖入到Palettes中,并且保存到Assets -> Tilemap -> Tiles -> Custom Tiles目录下。
确保这3个Tile的Collider Type为"Sprite"。
我们要做的是将一个Tilemap Collision 2D组件附加到我们的collision层上,通过碰撞器可以防止玩家穿透他们。
(2)给玩家添加box collider组件
给玩家添加Box Collider 2D组件。
修改Offset和Size的值,使得碰撞器只出现在玩家的脚下。
(3)绘制Collisions Tilemap
先给房屋添加Custom Tiles中的Tilemap,Target选择"Collisions"对象。
绘制后的效果如下:
(4)Collisions对象添加Tilemap Collider组件
此时角色不能再穿透蓝色标记部分的区域。
反勾选Tilemap Renderer组件,使得Collisions对象(蓝色部分)不要显示出来。
(5)添加Composite Collider组件
此时在Scene界面中显示如下:
每一个绿色边缘的方块代表一个碰撞器,当角色移动时可能要触发与N个碰撞体的碰撞检测,这个效率太低了。
所以,需要把所有这些合并起来。一个区域设置为一个单独的碰撞器即可。所以连在一起的区域的创建一个复合碰撞器。
Collisions对象添加Composite Collider 2D组件,并且设置Geometry Type为"Polygons"。
Collisions对象的Tilemap Collider 2D组件下,勾选"Used By Composite"。
此时我们看到原来N个碰撞器合并成了一个平铺的多边形的碰撞器。
为了提高性能,设置Collisions对象下Rigidbody 2D组件的Body Type属性为"Static"。
(6)整个Scene绘制Collisions对象
重新打开Collisions的Tilemap Renderer组件进行绘制。
绘制完毕后再反选"Tilemap Renderer"组件进行关闭。
7、添加树
在Hierarchy -> Scene1_Farm下创建空物体命名为Scenary。
然后在Scenary下创建空物体命名为Bushes。
在Assets -> Prefabs下创建目录Scenary,以便保存相关的预设体。
(1)创建Bush
Assets -> Sprites -> Sprite Textures -> Scenary下,将TumbleweedThistle放到Scene中,并且Hierarchy放到Scenary -> Bushes下。
设置TumbleweedThistle属性如下:
为了让角色不能穿透Bush,给TumbleweedThistle对象添加Box Collider 2D组件,其属性设置如下:
TumbleweedThistle对象修改让所有预设体生效,点击其Overrides选项,再点击"Apply All"。
此时再查看预设体的Inspector,看到也已经有了Box Collider 2D组件。
然后在Scene里面放置多个Bush。
(2)创建风景树
使用Assets -> Sprites -> Sprite Textures -> Scenary下的WildOakScenary素材。
相关的设置如下:
这个树只是作为风景树使用,是不能采伐的。
然后在Scene中多创建一些WildOakScenary对象。
(3)创建可砍伐树
使用Assets -> Sprites -> Sprite Textures -> Trees下的CanyonOa素材。
设置Sorting Layer为1,其Order in Layer为1,因为要比Trunk的优先级要高。然后放到Prefab目录下。
Trunk素材 也在Assets -> Sprites -> Sprite Textures -> Trees下。注意设置其Order in Layer为0。
然后在Scene中多创建一些CanyonOa对象。
最终效果如下: