01简介
该学习案例来自b站up主M_Studio的系列视频制作Roguelike随机地下城,此篇博客为案例学习笔记
Notice
1.该项目不包含包括敌人在内的一些游戏元素,仅为具有基础功能的demo
2.项目适用于所有版本的Unity,不需要其他项目基础
02 生成随机房间
素材预处理
1.导入随机房间的像素图片素材
2.修改图片在Unity中使用时的相对像素大小(一个Unity单位显示几个图片像素)
3.修改精灵图片类型为Multiple,使图片可以进行分割
4.修改 Filter Mode 属性为Point,以避免画面变糊
(解释如下,来自https://blog.youkuaiyun.com/candycat1992/article/details/22794773)
Filter Mode 当该纹理由于3D变换进行拉伸时,它将如何被过滤插值。共有三种选择:
Point 单点插值,纹理将变得块状化(blocky up close);
Bilinear 双线性插值,纹理将变得模糊(blurry up close);
Trilinear 三线性插值,类似Bilinear,但是纹理还会在不同的mip水平之间(between the different mip levels)进行模糊;
————————————————
版权声明:本文为优快云博主「妈妈说女孩子要自立自强」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/candycat1992/article/details/22794773
5.素材本身是64x32,此处使用时考虑为最大数值,故将 Max Size 属性修改为64
6.将 Compression 属性修改为None,以保证画面的锐度
7.保存如上操作后,在 Sprite Editor 中开始对图片进行分割。由于图片本身是未经处理的图片资源,使用Automatic分割类型无法将整体相互连接的图片分割成目标单位,因此在这里需要选择分割类型Grid By Cell Count(根据元素数量进行网格分割)。图片本身拥有规律的布局,根据单位元素的排布选择适当的行列数值进行分割即可得到所需的素材。
完成后,点击Apply保存
场景预处理
1.将分割完成后的房间模板图片中的基础房间模板(白色)拖入场景,命名为BasicRoom,并保存为预制体
2.创建空物体RoomGenerator,用来控制场景中房间的生成。该空物体包含子空物体Point,用于指示房间生成位置
脚本RoomGenerator
该脚本用于处理随机房间的基本生成逻辑(存在缺陷)
编程实现如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class RoomGenerator : MonoBehaviour
{
public enum Direction {
up, down, left, right };//用于控制房间生成方向的枚举类型
public Direction direction;
[Header("房间信息")]
public GameObject roomPrefab;//房间预制体
public int roomNumber;//房间数量
public Color startColor, endColor;//起始房间颜色
public GameObject endRoom;
[Header("位置控制")]
public Transform genetorPoint;//生成位置
public float xOffest;//水平偏移量
public float yOffest;//竖直偏移量
public LayerMask roomLayer;
public List<GameObject> rooms = new List<GameObject>();//存储房间的列表
private void Start()
{
for (int i = 0; i < roomNumber; i++)//摁两下Tab自动生成
{
rooms.Add(Instantiate(roomPrefab, genetorPoint.position, Quaternion.identity));
//在指定生成位置生成相应预制体的房间(先生成初始房间,之后的房间在生成时位置会根据下方函数变换),旋转属性一致不变
//改变Point的位置
ChangePointPosition();
}
//改变起始和终点房间的颜色
rooms[0].GetComponent<SpriteRenderer>().color = startColor;
//rooms[roomNumber - 1].GetComponent<SpriteRenderer>().color = endColor;
//终点房间应当距离起始房间较远,如上方式确定的最后生成的房间不一定具有合适的距离
foreach (var room in rooms)
{
endRoom = rooms[0];
if (room.transform.position.sqrMagnitude > endRoom.transform.position.sqrMagnitude)
{
endRoom = room;
}
//sqrMagnitude用于比较两个Vector3的大小(相比magnitude精度有损失)
//通过比较房间中心点的向量大小选择最远房间(? 似乎存在问题)
}
endRoom.GetComponent<SpriteRenderer>().color = endColor;
}
private void Update()
{
if (Input.anyKeyDown)//按下任意键重新生成
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void ChangePointPosition()
{
do
{
direction = (Direction)Random.Range(0, 4);//随机赋予变换方向变量direction上下左右中的某个数值
//Random.Range包含左边界值,不包含右边界值
//int不能隐式转换为enum
switch (direction)//通过switch完成房间生成点的位置变换
{
case Direction.up:
genetorPoint.position += new Vector3(0, yOffest, 0);
break;
case Direction.down:
genetorPoint.position += new Vector3(0, -yOffest, 0);
break;
case Direction.left:
genetorPoint.position += new Vector3(-xOffest, 0, 0);
break;