方案一:单纯使用随机数

思路:单纯随机实例化各种位置和大小的cube,生成墙壁,并且用不同的颜色(随机颜色)标识

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomBasedCreater : MonoBehaviour {
    /// <summary>
    /// 基本的地图土块元素的prefab,必须填
    /// </summary>
    public GameObject _Cube;
    /// <summary>
    /// 地板的Prefab,必须填
    /// </summary>
    public GameObject _Ground;


    //public Texture2D tex;

       /// <summary>
       /// 创造的地图图块数量
       /// </summary>
    [SerializeField]
    int CubesAmount;


    // Use this for initialization
    void Start()
    {
        //开始创建墙壁
        StartCoroutine(CreatMapBuildWalls(Mathf.Sqrt(CubesAmount),10));
        //开始创建地图内容
        StartCoroutine(CreatMapRandomly());


    }

    /// <summary>
    /// 创建墙的协程
    /// </summary>
    /// <param name="halfLength">边长的一半,一般是置为Mathf.Sqrt(CubesAmount)</param>
    /// <param name="height">墙的高度</param>
    /// <returns></returns>
    IEnumerator CreatMapBuildWalls(float halfLength,float height)
    {
        List<Vector3> Pos = new List<Vector3>();
        Pos.Add(new Vector3(-halfLength, 0, 0));
        Pos.Add(new Vector3(halfLength, 0, 0));
        Pos.Add(new Vector3(0, 0, -halfLength));
        Pos.Add(new Vector3(0, 0, halfLength));
        foreach (Vector3 v in Pos)
        {
            GameObject go = Instantiate(_Cube, v, Quaternion.identity,transform) as GameObject;
            if (go.transform.position.x == 0f)
            {
                go.transform.localScale = new Vector3(2 * halfLength, 10, 1);
            }
            else
            {
                go.transform.localScale = new Vector3(1, 10, 2 * halfLength);
            }
            //可以改变墙创建的速度
            yield return new WaitForSeconds(1);
        }


    }

    /// <summary>
    /// 随机创建地图的图块协程
    /// </summary>
    /// <returns></returns>
    IEnumerator CreatMapRandomly()
    {
        GameObject Ground = Instantiate(_Ground, transform);
        Transform GroundTransform = Ground.transform;
        float _scale = Mathf.Sqrt(CubesAmount);
        //这个参数用来调节地板大小
        GroundTransform.localScale = new Vector3(_scale / 5, _scale, _scale / 5);
        for (int i = 0; i <= CubesAmount; i++)
        {
            //生成的区域范围(调整来控制生成的位置范围
            //   Vector3 pos = new Vector3(_scale*SmoothRandom.Get(_scale) , 0, _scale * SmoothRandom.Get(_scale));

            Vector3 pos = new Vector3(Random.Range(-_scale, _scale), 0, Random.Range(-_scale, _scale));
            //Vector3 pos = Mathf.Sqrt(CubesAmount) * SmoothRandom.GetVector3(1000);

            //下面是一个生成圆形区域的例子.类似地,可以用这个方法来生成一些其他的图形,只要确定其对应的函数就可以了
            //分割线-----------------------------------------------------
            //  float _t = Random.Range(-_scale, _scale);
            //  Vector3 pos = new Vector3(_t*Mathf.Sin(_t),0,_t*Mathf.Cos(_t));
            //分割线---------------------------------------------------

            GameObject _go = Instantiate(_Cube, pos, Quaternion.identity, transform) as GameObject;
            //随机颜色
           _go.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
            //随机大小(可以调整
            float rfloat = Random.Range(1, 5f);
            float yfloat = Random.Range(1, 10f);
            _go.transform.localScale = new Vector3(rfloat, yfloat, rfloat);
            //生成速度
            yield return new WaitForSeconds(0.001f);
            print(i);
        }
    }
}

 

大概效果如图

感觉非常杂乱无章

如果把生成的cube数目扩大,也许有能用的部分。但是要控制cube的scale的取值范围,最好是通过实验得到一个比较符合需求的scale

 方案二:读取图像,然后做运算

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 使用这个类需要注意的是,sourceTex的属性必须将Read/Write Enable设为true(在Advanced选项卡里
/// </summary>
public class ImageBasedCreater : MonoBehaviour {
    //游戏物体的List
    private List<GameObject> _ListOfGameObjects;
    //源图像
    public Texture2D sourceTex;
    //生成物体的Prefab
    public GameObject _Cube;

    void Start()
    {
        //新建物体的列表
        _ListOfGameObjects = new List<GameObject>();
        //协程生成
        StartCoroutine(GenerateImageCubes());

    }

    /// <summary>
    /// 根据图像生成cube地图的协程
    /// </summary>
    /// <returns></returns>
    IEnumerator GenerateImageCubes()
    {
        //得到源图像的颜色数组
        Color[] pix = sourceTex.GetPixels(0, 0, sourceTex.width, sourceTex.height);
        //迭代次数
        int i = 0;

        //生成位置
        Vector3 pos = new Vector3();

        //生成的正方形边长
        float fx = Mathf.Sqrt(pix.Length);

        //单次生成数目的计数器
        int index = 0;

        //生成的Cube对象
        GameObject go;

        //遍历颜色数组生成地图
        foreach (var c in pix)
        {

            pos.x = i / fx;
            pos.z = i % fx;
     //if (!(c.r <= 100f/225f && c.g <= 100f / 225f && c.b <= 100f / 225f) ){ 
            go = Instantiate(_Cube, pos, Quaternion.identity);

            //生成的cube的高度的表达式,可以修改
            //float Height= (c.r * c.g * c.b) * 20;
            float Height = 1;
            go.transform.localScale = new Vector3(1, Height, 1);

            //生成原图对应的颜色
            go.GetComponent<MeshRenderer>().material.color = c;
            _ListOfGameObjects.Add(go);
   //}

         //循环计数器的递增
            i++;

            //     print(c);


            print("num:" + i + "  " + c);

            //单次生成数目计数器的递增
            index++;
            //控制每次调用生成的cube数目
            if (index >= 127)
            {
                index = 0;
                yield return 0;
            }

        }
    }
}

 

然后看下范例

也可以用来生成一些有趣的图形,比如

Chorme图标

UNITY图标

 

缺点:

可以使用的图形实在是太小了。这种直接生成游戏物体的行为是非常消耗资源的

 

第三种方法:动态生成mesh

版权声明:本文为Ash-game原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Ash-game/p/7481739.html