文章目录
- 吐槽
- 开启 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 : 测试 打 ABusing 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 & unloadingusing 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/Assetsvar projectPath = Application.dataPath.Replace("/Assets", "");//Debug.Log($"projectPath : {projectPath}"); // projectPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unloadvar platformABPath = $"{projectPath}/{buildTarget}/ABs";//Debug.Log($"platformABPath : {platformABPath}"); // projectPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unloadvar 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_1if (!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 depsvar 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 abvar 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