文章目录
- 吐槽
- 开启 Log Shader Compilation
- 实践
- 资源准备
- Build AB
- Testing Script
- Shader Compiled Log
 
- Project
吐槽
先说一下,最近几天前,纷纷看到 unity install fee 的天才收费方案
 真的忍不住吐槽,我只想说: “no zuo no die”
(吃相太难看了)
开启 Log Shader Compilation
如果要做变体优化,或是 Shader.CreateGPUProgram 的 CPU 卡顿优化
 都可以使用 Shader Compiled Log,只要在开启:Project Settings/Graphics/Shader Loading/Log Shader Compilation 即可

这样的话,就可以真机上查看编译情况,每个以 Compiled Log 都是对应 Shader.CreateGPUProgram,因此如果要做: 变体优化,变体预热,都是一个比较好的调试Log
实践

资源准备
顺便编写简单的 shader,创建 material,创建 prefab
 设置 AB 信息,build AB
如下

Build AB
// jave.lin : 测试 打 AB
using System.IO;
using UnityEditor;
using UnityEngine;
public class TestingBuildAB : MonoBehaviour
{
    [MenuItem("实用工具/BuildAB")]
    public static void Build()
    {
        var curBuildTarget = EditorUserBuildSettings.activeBuildTarget;
        var outputPath = $"{curBuildTarget}/ABs";
        try
        {
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }
            BuildPipeline.BuildAssetBundles(
                outputPath,
                BuildAssetBundleOptions.ChunkBasedCompression
                | BuildAssetBundleOptions.DeterministicAssetBundle,
                 curBuildTarget);
            EditorUtility.DisplayDialog("Build ABs Result", $"Build {outputPath} Successfully!", "OK");
        }
        catch (System.Exception er)
        {
            Debug.LogError(er);
            EditorUtility.DisplayDialog("Build ABs Result", $"Build {outputPath} Failure! See Console Plz.", "OK");
        }
    }
}
Testing Script
// jave.lin : 测试 ab loading & unloading
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestingScript : MonoBehaviour
{
    private Dictionary<string, AssetBundle> loaded_AB_Dict = new Dictionary<string, AssetBundle>();
    private Dictionary<string, bool> isLoadByMajor_Dict = new Dictionary<string, bool>();
    private AssetBundleManifest manifest;
    private bool isLoadedManifest;
    private AssetBundleManifest GetManifest(string platform = "Android")
    {
        if (manifest == null)
        {
            var buildTarget = platform;
            var projectPath = Application.dataPath.Replace("/Assets", "");
            var platformABPath = $"{projectPath}/{buildTarget}/ABs";
            var manifest_bundle = AssetBundle.LoadFromFile($"{platformABPath}/ABs");
            manifest = manifest_bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
            //Debug.Log($"loaded manifest : {platformABPath}, manifest : {manifest}");
        }
        return manifest;
    }
    private AssetBundle LoadAB(string abName, bool isMajorAB)
    {
        ///*
        //shader.ab // all shader
        //* common.svc
        //* height_fog.svc
        //* gi.svc
        //* xxx.svc
        // * 
        // */
        //AssetBundle ab = AssetBundle.LoadFromFile("shaders.ab");
         1. 游戏通用 shader warmup (可能会卡顿,因为编译时间长),注意: 一般不用 warmup
        //ab.LoadAsset<ShaderVariantCollection>("common.svc").WarmUp(); // 一般不用 warmup
         2. 进入一些需要 height fog 的场景
        //ab.LoadAsset<ShaderVariantCollection>("height_fog.svc").WarmUp();
         3. 进入一些【不】需要 height fog,但需要 gi 的场景,但是这块管理很有风险,我记得 unity 的 shader一旦 Shader.Find 不到会导致闪退
        //GameObject.Destroy(ab.LoadAsset<Shader>("height_fog1.shader"));
        //GameObject.Destroy(ab.LoadAsset<Shader>("height_fog2.shader"));
        //ab.LoadAsset<ShaderVariantCollection>("gi.svc").WarmUp();
         4. 再次进入需要 height fog ,不需要 gi的场景
        //GameObject.Destroy(ab.LoadAsset<Shader>("gi.shader"));
        //ab.LoadAsset<Shader>("height_fog1.shader"); // 之前 destroy ,现在重现 load 回来
        //ab.LoadAsset<Shader>("height_fog2.shader"); // 之前 destroy ,现在重现 load 回来
        //ab.LoadAsset<ShaderVariantCollection>("height_fog.svc").WarmUp();
        var buildTarget = "Android";
        //Debug.Log($"Application.dataPath : {Application.dataPath}"); // Application.dataPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unload/Assets
        var projectPath = Application.dataPath.Replace("/Assets", "");
        //Debug.Log($"projectPath : {projectPath}"); // projectPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unload
        var platformABPath = $"{projectPath}/{buildTarget}/ABs";
        //Debug.Log($"platformABPath : {platformABPath}"); // projectPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unload
        var ps_ab_path = $"{platformABPath}/{abName.ToLower()}";
        //Debug.Log($"ps_ab_path : {ps_ab_path}"); // ps_ab_path : e:/workfiles/unitystudies/testing_ab_load_unload/testingeffect_1
        if (!loaded_AB_Dict.TryGetValue(abName, out var ab))
        {
            ab = AssetBundle.LoadFromFile(ps_ab_path);
            loaded_AB_Dict.Add(abName, ab);
            if (isMajorAB)
            {
                isLoadByMajor_Dict[abName] = isMajorAB;
            }
            Debug.Log($"loaded ab : {abName}");
        }
        return ab;
    }
    private bool UnLoadAB(string abName)
    {
        if (loaded_AB_Dict.TryGetValue(abName, out var ab))
        {
            ab.Unload(true);
            loaded_AB_Dict.Remove(abName);
            Debug.Log($"unload ab : {abName}");
            return true;
        }
        return false;
    }
    private int instCount;
    public void OnLoadPS_Btn()
    {
        //var manifest = GetManifest();
        // load deps
        var abNames = new string[] 
        {
            "Assets/Textures/tex_1.png",
            "Assets/Textures/tex_2.png",
            "Assets/Materials/ps_mat_1.mat",
            "Assets/Materials/ps_mat_2.mat",
        };
        var isAnyChildABUnload = false;
        foreach (var abName1 in abNames)
        {
            if (!loaded_AB_Dict.ContainsKey(abName1))
                isAnyChildABUnload = true;
            LoadAB(abName1, false);
        }
        // load main ab
        var abName = "Assets/Effects/TestingEffect_1.prefab";
        if (isAnyChildABUnload)
        {
            UnLoadAB(abName);
        }
        var ab = LoadAB(abName, true);
        var prefab = ab.LoadAsset<GameObject>(abName.ToLower());
        var inst = GameObject.Instantiate<GameObject>(prefab);
        inst.transform.position = Vector3.zero + Vector3.up * (instCount++);
    }
    public void OnUnloadPS_Btn()
    {
        var abName = "Assets/Effects/TestingEffect_1.prefab";
        UnLoadAB(abName);
    }
    public void OnUnloadMat_Btn()
    {
        var abName = "Assets/Materials/ps_mat_2.mat";
        UnLoadAB(abName);
    }
    public void OnUnloadTex_Btn()
    {
        var abName = "Assets/Textures/tex_2.png";
        UnLoadAB(abName);
    }
    public void OnLoadMat_Btn()
    {
        var abName = "Assets/Materials/ps_mat_2.mat";
        LoadAB(abName, false);
    }
}
Shader Compiled Log

Project
TestingShaderCompiledLog.rar
 提取码:yv4d



















