【Unity】物体体素化(一)

前几天看了一篇体素渲染技术的文章,就突然想起这个挖了很久的坑……

话说不管是像素化风格还是体素化风格都好可爱啊!

感觉像在玩我的世界。
物体体素化

之前写的时候也没细想,用的简单粗暴的蠢方法,性能耗的一批又有诸多限制。

原理很是简单粗暴,把原物体加上collider和刚体,然后在它的bounds里生成指定大小的cube,然后原物体上绑上触发检测的脚本,如果碰到了cube,就修改cube的tag为“cube”,最后把tag为“cube”的cube网格合并,再把cube全都destroy掉,把生成的网格存下来就行啦。

现在看看简直蠢爆了哈哈哈哈哈,下次试试用shader做做看,等我把那坨屎一样的游戏代码写完……

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

public class TiSuHua : MonoBehaviour
{
    public GameObject prefab;
    public Material material;

    private Transform newGo;
    private Bounds bounds;

    [Range(0.2f, 1.0f)]
    public float cubeSize = 0.5f;

    private MeshFilter[] cubeMeshs;

    private void CreateTiSu()
    {
        int widthCubeCount = (int)(bounds.size.x / cubeSize + 1);
        int lengthCubeCount = (int)(bounds.size.z / cubeSize + 1);
        int heightCubeCount = (int)(bounds.size.y / cubeSize + 1);

        float cubePositionX = bounds.center.x - cubeSize * widthCubeCount / 2 + cubeSize / 2;
        float cubePositionY = bounds.center.y - cubeSize * heightCubeCount / 2 + cubeSize / 2;
        float cubePositionZ = bounds.center.z - cubeSize * lengthCubeCount / 2 + cubeSize / 2;

        for (int i = 0; i < heightCubeCount; i++)
        {
            for (int j = 0; j < lengthCubeCount; j++)
            {
                for (int k = 0; k < widthCubeCount; k++)
                {
                    Vector3 position = new Vector3(cubePositionX, cubePositionY, cubePositionZ);
                    cubePositionX += cubeSize;
                    CreateCube(position);
                }
                cubePositionZ += cubeSize;
                cubePositionX = bounds.center.x - cubeSize * widthCubeCount / 2 + cubeSize / 2;
            }
            cubePositionY += cubeSize;
            cubePositionX = bounds.center.x - cubeSize * widthCubeCount / 2 + cubeSize / 2;
            cubePositionZ = bounds.center.z - cubeSize * lengthCubeCount / 2 + cubeSize / 2;
        }
    }

    private void CreateCube(Vector3 position)
    {
        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.position = position;
        cube.transform.localScale = new Vector3(cubeSize, cubeSize, cubeSize);
        cube.GetComponent<BoxCollider>().isTrigger = true;
        cube.transform.parent = newGo;
    }

    void Start()
    {
        GameObject go = Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject;

        bounds = go.GetComponent<Renderer>().bounds;

        go.AddComponent<Rigidbody>();
        go.GetComponent<Rigidbody>().isKinematic = true;
        go.AddComponent<CollisionTest>();

        newGo = new GameObject("newGo").transform;
        newGo.gameObject.AddComponent<MeshFilter>();
        newGo.gameObject.AddComponent<MeshRenderer>();

        CreateTiSu();

        cubeMeshs = newGo.GetComponentsInChildren<MeshFilter>();

        Destroy(go);
    }

    private bool alreadyCombineCube = false;

    private void LateUpdate()
    {
        if (!alreadyCombineCube)
        {
            List<CombineInstance> combines = new List<CombineInstance>();

            for (int i = 0; i < cubeMeshs.Length; i++)
            {
                if (cubeMeshs[i].tag == "cube")
                {
                    combines.Add(new CombineInstance()
                    {
                        mesh = cubeMeshs[i].sharedMesh,
                        transform = cubeMeshs[i].transform.localToWorldMatrix
                    });
                }

                cubeMeshs[i].transform.parent = null;
                Destroy(cubeMeshs[i].gameObject);
            }

            CombineInstance[] cb = combines.ToArray();

            newGo.GetComponent<MeshFilter>().mesh.CombineMeshes(cb);
            newGo.GetComponent<MeshRenderer>().material = material;

            AssetDatabase.CreateAsset(newGo.GetComponent<MeshFilter>().mesh, "Assets/" + prefab.name + "VoxelMesh.asset");
            PrefabUtility.CreatePrefab("Assets/" + prefab.name + "Voxel.prefab", newGo.gameObject);
            AssetDatabase.SaveAssets();

            Instantiate(newGo.gameObject,prefab.transform.position,Quaternion.identity);
        }

        alreadyCombineCube = true;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值