技术要点:
- Resources 资源加载
- Quaternion 四元数
- Mathf 数学计算
1. 通过Resources动态加载方块
首先在 Project 面板中创建 Resources 文件夹,将需要加载的方块拖入Resources文件夹里面。
创建 MapManager 脚本文件
通过 Resources.Load(“资源名”) 来获得方块预制体
/// <summary>
/// 地图管理器
/// </summary>
public class MapManager : MonoBehaviour
{
private GameObject cubeTile;
private void Start()
{
cubeTile = Resources.Load("Cube") as GameObject;
}
}
2. 代码生成地图菱形布局
两层 for 循环嵌套生成长方形的地面效果
/// <summary>
/// 地图管理器
/// </summary>
public class MapManager : MonoBehaviour
{
private GameObject cubeTile;
// 存储方块位置
Vector3 cubePos;
private void Start()
{
// 动态加载获得 cube 预制体
cubeTile = Resources.Load("Cube") as GameObject;
CreateMap();
}
private void CreateMap()
{
// 行和列可以自定义
// 10 行
for (int i = 0; i < 10; i++)
{
// 5 列
for (int j = 0; j < 5; j++)
{
// 每个立方体长度为 1 米
cubePos = new Vector3(i * 1, 0, j * 1);
Instantiate(cubeTile, cubePos, Quaternion.identity);
}
}
}
}
等腰直角三角形求底边实现单排菱形平铺
等腰直角三角形求底边:2 的平方根 乘以 直角边长;
Unity3D 代码实现:Mathf.Sqrt(2)* n;
使用 Quaternion.Euler(Vector3)可以将三维向量转换为四元数
/// <summary>
/// 地图管理器
/// </summary>
public class MapManager : MonoBehaviour
{
private GameObject cubeTile;
// 存储方块位置
Vector3 cubePos;
// 求底边
private float bottomLength = Mathf.Sqrt(2);
private void Start()
{
// 动态加载获得 cube 预制体
cubeTile = Resources.Load("Cube") as GameObject;
CreateMap();
}
private void CreateMap()
{
// 行和列可以自定义
// 10 行
for (int i = 0; i < 10; i++)
{
// 5 列
for (int j = 0; j < 5; j++)
{
// 每个立方体长度为 1 米
cubePos = new Vector3(i * bottomLength, 0, j * bottomLength);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0,45,0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
}
}
}
}
实现双排菱形平铺,实现方法跟单排一样,只不过双数排菱形位置需要偏移,偏移量为半个底边长度。
private void CreateMap()
{
// 行和列可以自定义
// 10 行
for (int i = 0; i < 10; i++)
{
// 单排 5 列
for (int j = 0; j < 5; j++)
{
// 每个立方体长度为 1 米
cubePos = new Vector3(i * bottomLength, 0, j * bottomLength);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0,45,0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
}
// 双排 4列
for (int j = 0; j < 4; j++)
{
// 双数排菱形位置需要偏移,偏移量为半个底边长度
cubePos = new Vector3(i * bottomLength + bottomLength / 2, 0, j * bottomLength + bottomLength / 2);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0, 45, 0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
}
}
}
3.地图连续生成
声明一个list来存储地图数据
// 地图数据存储
public List<GameObject[]> cubeTiles = new List<GameObject[]>();
声明一个GameObject数组存储每行地图数据
private GameObject[] item
list 和 数组 存储数据
private void CreateMap()
{
// 行和列可以自定义
// 10 行
for (int i = 0; i < 10; i++)
{
// 存储单排每行数据
item = new GameObject[5];
// 单排 5 列
for (int j = 0; j < 5; j++)
{
// 每个立方体长度为 1 米
cubePos = new Vector3(i * bottomLength, 0, j * bottomLength);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0,45,0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
item[j] = cubeObj;
}
// 将单排每行存储的数组存到list里面
cubeTiles.Add(item);
item = new GameObject[4];
// 双排 4列
for (int j = 0; j < 4; j++)
{
// 双数排菱形位置需要偏移,偏移量为半个底边长度
cubePos = new Vector3(i * bottomLength + bottomLength / 2, 0, j * bottomLength + bottomLength / 2);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0, 45, 0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
itme[j] = cubeObj;
}
cubeTiles.Add(item);
}
}
通过按键生成地图(可以自己调,为了方便测试我使用按键的形式生成)
思路是获得地图的最后一块方块的x轴方向减去底部的一半,然后将值传给CreateMap函数,生成方块时给x轴加上偏移量
private void Update()
{
if (Input.GetKeyDown(KeyCode.K))
{
float offsetZ = cubeTiles[cubeTiles.Count - 1][0].transform.position.x + bottomLength / 2;
CreateMap(offsetZ);
}
}
private void CreateMap(float offsetZ)
{
// 行和列可以自定义
// 10 行
for (int i = 0; i < 10; i++)
{
// 存储单排每行数据
item = new GameObject[5];
// 单排 5 列
for (int j = 0; j < 5; j++)
{
// 每个立方体长度为 1 米
cubePos = new Vector3(offsetZ + i * bottomLength, 0, j * bottomLength);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0,45,0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
item[j] = cubeObj;
}
// 将单排每行存储的数组存到list里面
cubeTiles.Add(item);
item = new GameObject[4];
// 双排 4列
for (int j = 0; j < 4; j++)
{
// 双数排菱形位置需要偏移,偏移量为半个底边长度
cubePos = new Vector3(offsetZ + i * bottomLength + bottomLength / 2, 0, j * bottomLength + bottomLength / 2);
GameObject cubeObj = Instantiate(cubeTile, cubePos, Quaternion.Euler(0, 45, 0));
// 将生成的物体变成子物体
cubeObj.transform.SetParent(transform);
itme[j] = cubeObj;
}
cubeTiles.Add(item);
}
}