[Unity]变体收集器开发

2020/10 28 21:10

写一个脚本,把Prefab和Material全加载一遍,代码如下。

#if UNITY_EDITOR

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

// 变体收集器
public class ShaderVarCollect : MonoBehaviour
{
    const int TaskNum = 20;

    void Start()
    {
        StartCoroutine(UpdateTask());
    }

    IEnumerator UpdateTask()
    {
        string[] prefabAssets = System.IO.Directory.GetFiles("Assets/", "*.prefab", System.IO.SearchOption.AllDirectories);

        yield return null;

        List<Object> objs = new List<Object>();
        int sec = Mathf.CeilToInt(prefabAssets.Length / TaskNum);
        for(int secIndex = 0; secIndex < sec; ++secIndex)
        {
            foreach(var obj in objs)
            {
                Destroy(obj);
            }
            objs.Clear();

            var baseIndex = secIndex * TaskNum;
            for(int i=0; i<TaskNum; ++i)
            {
                var currIndex = baseIndex + i;
                if (currIndex < prefabAssets.Length)
                {
                    var tobj = AssetDatabase.LoadAssetAtPath(prefabAssets[currIndex], typeof(UnityEngine.Object));
                    if (tobj != null)
                    {
                        objs.Add( Instantiate(tobj) );
                    }
                }
            }

            yield return null;
            yield return null;
        }

        foreach(var obj in objs)
        {
            Destroy(obj);
        }
        objs.Clear();


        string[] matList = System.IO.Directory.GetFiles("Assets/", "*.mat", System.IO.SearchOption.AllDirectories);

        yield return null;

        List<MeshRenderer> spheres = new List<MeshRenderer>();

        for(int i=0; i<TaskNum; ++i)
        {
            spheres.Add( GameObject.CreatePrimitive(PrimitiveType.Sphere).GetComponent<MeshRenderer>() );
        }

        sec = Mathf.CeilToInt(matList.Length / TaskNum);
        for(int secIndex = 0; secIndex < sec; ++secIndex)
        {
            var baseIndex = secIndex * TaskNum;
            for(int i=0; i<TaskNum; ++i)
            {
                var currIndex = baseIndex + i;
                if (currIndex < matList.Length)
                {
                    var tobj = AssetDatabase.LoadAssetAtPath(matList[currIndex], typeof(UnityEngine.Material)) as UnityEngine.Material;
                    if (tobj != null)
                    {
                        spheres[i].sharedMaterial = tobj;
                    }
                }
            }

            yield return null;
            yield return null;
        }
    }
}

#endif

搞个空scene,挂上脚本跑一启遍;
然后在Project Settings / Graphics 中,拉到最后面,
在Shader Preloading 页,点“Save to asset…”
保存变体收集器到Shader的AB包中即可。