【Unity技术积累】代码生成菱形地图

技术要点:

  • 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);
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值