zoukankan      html  css  js  c++  java
  • Unity性能优化之特效合并

    特效合并,意思是说将粒子所用的零碎图片,以shader为单位合并成一张图集,好处就是可以降低draw call。试想,合并前每个粒子使用一个material,而每一个material就要占用一个drawcall,而合并后多个粒子可以用同一个material,这样就降低了drawcall,提升了性能。

    转载请注明出处:http://www.cnblogs.com/jietian331/p/8625078.html

    合并工具的代码如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.IO;
      4 using System.Linq;
      5 using System.Text;
      6 using UnityEditor;
      7 using UnityEngine;
      8 
      9 namespace AssetBundle
     10 {
     11     public class ParticleSystemCombiner : ScriptableObject
     12     {
     13         public const string
     14             AtlasFolder = "Assets/Cloth/Resources/ParticleSystemAtlas",
     15             ParticleAtlasPath = "Assets/Cloth/Resources/ParticleSystemAtlas/particle_atlas.prefab",
     16             SettingFilepath = "Assets/Editor/ParticleSystemCombinerSetting.csv";
     17 
     18         static string[] EffectObjFolders = new string[] 
     19         { 
     20             "Assets/Cloth/Resources/Effect/Cloth",
     21             "Assets/Cloth/Resources/Model/Equip",
     22         };
     23 
     24         static ParticleAtlases s_atlasesData;
     25         static List<string> s_materials;
     26         static Dictionary<string, int> s_texturesSize;
     27 
     28         static ParticleAtlases AtlasesData
     29         {
     30             get
     31             {
     32                 if (s_atlasesData == null)
     33                     s_atlasesData = AssetDatabase.LoadAssetAtPath<ParticleAtlases>(ParticleAtlasPath);
     34                 return s_atlasesData;
     35             }
     36         }
     37 
     38         static Dictionary<string, int> TexturesSize
     39         {
     40             get
     41             {
     42                 if (s_texturesSize == null)
     43                 {
     44                     s_texturesSize = new Dictionary<string, int>();
     45 
     46                     string[] lines = File.ReadAllLines(SettingFilepath);
     47                     bool decode = false;
     48                     foreach (var line in lines)
     49                     {
     50                         if (!decode)
     51                         {
     52                             if (line.StartsWith("# Texture Size"))
     53                             {
     54                                 decode = true;
     55                             }
     56                         }
     57                         else
     58                         {
     59                             if (line.StartsWith("#"))
     60                             {
     61                                 decode = false;
     62                             }
     63                         }
     64 
     65                         if (decode)
     66                         {
     67                             string[] words = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
     68                             if (words.Length > 1)
     69                             {
     70                                 string name = words[0];
     71                                 int size;
     72                                 int.TryParse(words[1], out size);
     73                                 if (size != 0)
     74                                     s_texturesSize[name] = size;
     75                             }
     76                         }
     77                     }
     78                 }
     79                 return s_texturesSize;
     80             }
     81         }
     82 
     83 
     84         static List<string> NotCombineTextures
     85         {
     86             get
     87             {
     88                 List<string> list = new List<string>();
     89                 string[] lines = File.ReadAllLines(SettingFilepath);
     90                 bool decode = false;
     91                 foreach (var line in lines)
     92                 {
     93                     if (!decode)
     94                     {
     95                         if (line.StartsWith("# Not Combine Textures"))
     96                         {
     97                             decode = true;
     98                         }
     99                     }
    100                     else
    101                     {
    102                         if (line.StartsWith("#"))
    103                         {
    104                             decode = false;
    105                         }
    106                     }
    107 
    108                     if (decode)
    109                     {
    110                         string[] words = line.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    111                         if (words.Length > 0 && !string.IsNullOrEmpty(words[0]))
    112                         {
    113                             list.Add(words[0]);
    114                         }
    115                     }
    116                 }
    117                 return list;
    118             }
    119         }
    120 
    121         #region for build
    122 
    123         public static void ClearCache()
    124         {
    125             s_atlasesData = null;
    126             s_materials = null;
    127         }
    128 
    129         public static List<ParticleAtlases.TextureItem> GetParticlesUsedAtlas(GameObject effectObj)
    130         {
    131             List<ParticleAtlases.TextureItem> texturesData = new List<ParticleAtlases.TextureItem>();
    132             ParticleSystem[] particles = effectObj.GetComponentsInChildren<ParticleSystem>(true);
    133 
    134             foreach (ParticleSystem ps in particles)
    135             {
    136                 ParticleSystemRenderer render = ps.GetComponent<ParticleSystemRenderer>();
    137                 if (!render || !render.sharedMaterial)
    138                 {
    139                     Debug.LogWarning("Particle no material: " + ps.name);
    140                     continue;
    141                 }
    142 
    143                 Texture texture = render.sharedMaterial.mainTexture;
    144                 if (ps.textureSheetAnimation.enabled || !texture)
    145                     continue;
    146 
    147                 foreach (var atlasData in AtlasesData.Atlases)
    148                 {
    149                     foreach (var t in atlasData.Textures)
    150                     {
    151                         if (t.Name == texture.name)
    152                         {
    153                             texturesData.Add(t);
    154                             break;
    155                         }
    156                     }
    157                 }
    158             }
    159 
    160             return texturesData;
    161         }
    162 
    163         public static void ProcessEffectObj(GameObject obj)
    164         {
    165             ParticleSystem[] particles = obj.GetComponentsInChildren<ParticleSystem>(true);
    166 
    167             foreach (ParticleSystem ps in particles)
    168             {
    169                 ParticleSystemRenderer render = ps.GetComponent<ParticleSystemRenderer>();
    170                 if (!render || !render.sharedMaterial)
    171                 {
    172                     Debug.LogWarning("Particle no material: " + ps.name);
    173                     continue;
    174                 }
    175 
    176                 Texture texture = render.sharedMaterial.mainTexture;
    177                 if (ps.textureSheetAnimation.enabled || !texture)
    178                     continue;
    179 
    180                 ParticleAtlases.Atlas target = AtlasesData.Atlases.FirstOrDefault(a => a.Textures.Any(t => t.Name == texture.name && t.ShaderName == render.sharedMaterial.shader.name));
    181 
    182                 if (target != null)
    183                 {
    184                     ParticleLoader loader = ps.GetComponent<ParticleLoader>();
    185                     if (!loader)
    186                         loader = ps.gameObject.AddComponent<ParticleLoader>();
    187                     loader.TextureName = texture.name;
    188                     loader.ShaderName = render.sharedMaterial.shader.name;
    189                     render.sharedMaterial = null;
    190 
    191                     if (!ps.trails.enabled)
    192                         render.trailMaterial = null;
    193                 }
    194             }
    195 
    196             EditorUtility.SetDirty(obj);
    197             AssetDatabase.SaveAssets();
    198         }
    199 
    200         public static List<string> GetAllMaterials()
    201         {
    202             if (s_materials != null)
    203                 return s_materials;
    204 
    205             List<string> effects;
    206             Dictionary<Shader, List<ParticleSystem>> dic = GetAllParticles(out effects);
    207             s_materials = new List<string>();
    208 
    209             foreach (var pair in dic)
    210             {
    211                 foreach (ParticleSystem ps in pair.Value)
    212                 {
    213                     ParticleSystemRenderer r = ps.GetComponent<ParticleSystemRenderer>();
    214                     string path = AssetDatabase.GetAssetPath(r.sharedMaterial);
    215                     if (!s_materials.Contains(path))
    216                         s_materials.Add(path);
    217                 }
    218             }
    219 
    220             return s_materials;
    221         }
    222 
    223         #endregion
    224 
    225 
    226         [MenuItem("BuildTool/AssetBundle/Combine Particle System")]
    227         static void Init()
    228         {
    229             CombineAllEffectTextures();
    230 
    231             EditorUtility.DisplayDialog("finished", "All work finished.", "ok");
    232         }
    233 
    234         static Dictionary<Shader, List<ParticleSystem>> GetAllParticles(out List<string> effectObjs)
    235         {
    236             // 获取所有的粒子
    237             List<ParticleSystem> particlesList = new List<ParticleSystem>();
    238             List<string> objPaths = new List<string>();
    239             foreach (var effectObjFolder in EffectObjFolders)
    240             {
    241                 string[] paths = Directory.GetFiles(effectObjFolder, "*.prefab", SearchOption.AllDirectories);
    242                 objPaths.AddRange(paths);
    243             }
    244             effectObjs = new List<string>();
    245 
    246             foreach (string path in objPaths)
    247             {
    248                 string pathFixed = path.Replace("\", "/");
    249                 effectObjs.Add(pathFixed);
    250                 GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(pathFixed);
    251                 ParticleSystem[] particles = obj.GetComponentsInChildren<ParticleSystem>(true);
    252 
    253                 foreach (ParticleSystem ps in particles)
    254                 {
    255                     ParticleSystemRenderer r = ps.GetComponent<ParticleSystemRenderer>();
    256                     bool needCombine = !ps.textureSheetAnimation.enabled
    257                         && r.sharedMaterial
    258                         && r.sharedMaterial.shader.name != "Particles/Alpha Blended Premultiply"
    259                         && r.sharedMaterial.mainTexture
    260                         && r.sharedMaterial.mainTexture.width == r.sharedMaterial.mainTexture.height;
    261                     if (needCombine)
    262                         particlesList.Add(ps);
    263                 }
    264             }
    265 
    266             // 分类
    267             Dictionary<Shader, List<ParticleSystem>> dic = new Dictionary<Shader, List<ParticleSystem>>();
    268             foreach (ParticleSystem ps in particlesList)
    269             {
    270                 ParticleSystemRenderer r = ps.GetComponent<ParticleSystemRenderer>();
    271                 var shader = r.sharedMaterial.shader;
    272                 if (!dic.ContainsKey(shader))
    273                     dic[shader] = new List<ParticleSystem>();
    274                 dic[shader].Add(ps);
    275             }
    276 
    277             return dic;
    278         }
    279 
    280         public static List<string> CombineAllEffectTextures()
    281         {
    282             List<string> atlases = new List<string>();
    283 
    284             // 获取所有的粒子
    285             List<string> effects;
    286             Dictionary<Shader, List<ParticleSystem>> dic = GetAllParticles(out effects);
    287 
    288             // combine
    289             Dictionary<Texture2D, Material> dictTextures = new Dictionary<Texture2D, Material>();
    290             List<ParticleAtlases.Atlas> atlasesData = new List<ParticleAtlases.Atlas>();
    291             List<string> notCombineTextures = NotCombineTextures;
    292 
    293             foreach (var pair in dic)
    294             {
    295                 // get textures
    296                 dictTextures.Clear();
    297                 foreach (ParticleSystem ps in pair.Value)
    298                 {
    299                     ParticleSystemRenderer r = ps.GetComponent<ParticleSystemRenderer>();
    300                     Texture2D texture = (Texture2D)r.sharedMaterial.mainTexture;
    301                     if (!notCombineTextures.Contains(texture.name) && !dictTextures.ContainsKey(texture))
    302                         dictTextures.Add(texture, r.sharedMaterial);
    303                 }
    304 
    305                 if (dictTextures.Count < 2)
    306                     continue;
    307 
    308                 Texture2D[] texturesArray = dictTextures.Keys.ToArray();
    309 
    310                 // combine texture
    311                 string atlasName = string.Format("ParticleAtlas_{0}", Path.GetFileNameWithoutExtension(pair.Key.name));
    312                 string atlasPath = string.Format("{0}/{1}.png", AtlasFolder, atlasName);
    313                 Uploader.CreateDirectory(atlasPath);
    314                 Rect[] rects;
    315                 Vector2[] textureSizes;
    316                 Texture2D atlas = CombineTextures(texturesArray, atlasPath, out rects, out textureSizes);
    317                 atlases.Add(atlasPath);
    318 
    319                 // create material
    320                 string matPath = string.Format("{0}/{1}.mat", AtlasFolder, atlasName);
    321                 Material mat = AssetDatabase.LoadAssetAtPath<Material>(matPath);
    322                 if (mat == null)
    323                 {
    324                     mat = new Material(pair.Key);
    325                     AssetDatabase.CreateAsset(mat, matPath);
    326                 }
    327                 mat.mainTexture = atlas;
    328 
    329                 // get config
    330                 ParticleAtlases.TextureItem[] texturesData = new ParticleAtlases.TextureItem[texturesArray.Length];
    331                 for (int i = 0; i < texturesArray.Length; i++)
    332                 {
    333                     Rect rect = rects[i];
    334                     Texture2D texture2D = texturesArray[i];
    335                     Vector2 textureSize = textureSizes[i];      // will resize temp texture, so cann't use texture2D.width
    336                     int numTilesX = (int)(atlas.width / textureSize.x);
    337                     int numTilesY = (int)(atlas.height / textureSize.y);
    338                     int colIndex = (int)(rect.x * numTilesX);
    339                     int rowIndex = (int)(numTilesY - 1 - rect.y * numTilesY);
    340                     int index = rowIndex * numTilesX + colIndex;
    341 
    342                     // get color
    343                     Material oldMat = dictTextures[texture2D];
    344                     Color32 oldColor = oldMat.GetColor("_TintColor");
    345                     string strColor = string.Format("{0}_{1}_{2}_{3}", oldColor.r, oldColor.g, oldColor.b, oldColor.a);
    346 
    347                     string shaderName = oldMat.shader.name;
    348 
    349                     int depth = oldMat.renderQueue;
    350 
    351                     texturesData[i] = new ParticleAtlases.TextureItem()
    352                     {
    353                         Color = oldColor,
    354                         Depth = depth,
    355                         Index = index,
    356                         Name = texture2D.name,
    357                         NumTilesX = numTilesX,
    358                         NumTilesY = numTilesY,
    359                         ShaderName = shaderName,
    360                     };
    361                 }
    362 
    363                 ParticleAtlases.Atlas atlasData = new ParticleAtlases.Atlas()
    364                 {
    365                     Material = mat,
    366                     Textures = texturesData,
    367                 };
    368                 atlasesData.Add(atlasData);
    369             }
    370 
    371             GameObject prefabObj = AssetDatabase.LoadAssetAtPath<GameObject>(ParticleAtlasPath);
    372             if (!prefabObj)
    373                 prefabObj = PrefabUtility.CreatePrefab(ParticleAtlasPath, new GameObject());
    374             ParticleAtlases atlasesCom = prefabObj.GetComponent<ParticleAtlases>();
    375             if (!atlasesCom)
    376                 atlasesCom = prefabObj.AddComponent<ParticleAtlases>();
    377             atlasesCom.Atlases = atlasesData.ToArray();
    378             prefabObj.name = Path.GetFileNameWithoutExtension(ParticleAtlasPath);
    379 
    380             EditorUtility.SetDirty(prefabObj);
    381             AssetDatabase.SaveAssets();
    382 
    383             Debug.Log("All cloth effect textures combine finished!");
    384 
    385             return atlases;
    386         }
    387 
    388         static Texture2D CombineTextures(Texture2D[] textures, string path, out Rect[] rects, out Vector2[] textureSizes)
    389         {
    390             if (textures == null || textures.Length < 1)
    391             {
    392                 Debug.LogError("None textures");
    393                 rects = null;
    394                 textureSizes = null;
    395                 return null;
    396             }
    397 
    398             string tempFolderName = "_TempImages";
    399             string tempFolder = "Assets/" + tempFolderName;
    400             AssetDatabase.DeleteAsset(tempFolder);
    401             AssetDatabase.CreateFolder("Assets", tempFolderName);
    402 
    403             List<string> newPaths = new List<string>();
    404             var newTextures = new Texture2D[textures.Length];
    405             textureSizes = new Vector2[textures.Length];
    406 
    407             // 将原来的图片复制一份出来
    408             for (int i = 0; i < textures.Length; i++)
    409             {
    410                 string texPath = AssetDatabase.GetAssetPath(textures[i]);
    411                 if (File.Exists(texPath))
    412                 {
    413                     string newPath = string.Format("{0}/{1}", tempFolder, Path.GetFileName(texPath));
    414                     AssetDatabase.CopyAsset(texPath, newPath);
    415                     newPaths.Add(newPath);
    416                 }
    417                 else
    418                 {
    419                     Debug.Log("File not exists: " + texPath);
    420                 }
    421             }
    422 
    423             // make it readable
    424             for (int i = 0; i < newPaths.Count; i++)
    425             {
    426                 string newPath = newPaths[i];
    427                 SetSourceTextureReadalbe(newPath);
    428                 Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(newPath);
    429                 textureSizes[i] = new Vector2(t.width, t.height);
    430 
    431                 // 去掉边缘的一个像素
    432                 if (t.width > 4)
    433                 {
    434                     for (int j = 0; j < t.width; j++)
    435                     {
    436                         t.SetPixel(j, 0, new Color(0, 0, 0, 0));
    437                         t.SetPixel(j, 1, new Color(0, 0, 0, 0));
    438                         t.SetPixel(j, t.height - 1, new Color(0, 0, 0, 0));
    439                         t.SetPixel(j, t.height - 2, new Color(0, 0, 0, 0));
    440                     }
    441                 }
    442 
    443                 if (t.height > 4)
    444                 {
    445                     for (int z = 0; z < t.height; z++)
    446                     {
    447                         t.SetPixel(0, z, new Color(0, 0, 0, 0));
    448                         t.SetPixel(1, z, new Color(0, 0, 0, 0));
    449                         t.SetPixel(t.width - 1, z, new Color(0, 0, 0, 0));
    450                         t.SetPixel(t.width - 2, z, new Color(0, 0, 0, 0));
    451                     }
    452                 }
    453 
    454                 newTextures[i] = t;
    455             }
    456 
    457             // pack
    458             Texture2D atlas = new Texture2D(1, 1, TextureFormat.ARGB32, false);
    459             rects = atlas.PackTextures(newTextures, 0, 4096, false);
    460 
    461             // save
    462             byte[] bytes = atlas.EncodeToPNG();
    463             File.WriteAllBytes(path, bytes);
    464             AssetDatabase.Refresh();
    465             AssetDatabase.SaveAssets();
    466 
    467             // setting
    468             TextureCompresser.CompressRGBA(path);
    469 
    470             // 删除临时目录
    471             AssetDatabase.DeleteAsset(tempFolder);
    472 
    473             AssetDatabase.Refresh();
    474             AssetDatabase.SaveAssets();
    475 
    476             return AssetDatabase.LoadAssetAtPath<Texture2D>(path);
    477         }
    478 
    479         static void SetSourceTextureReadalbe(string path)
    480         {
    481             string name = Path.GetFileNameWithoutExtension(path);
    482             int maxSize;
    483             TexturesSize.TryGetValue(name, out maxSize);
    484             if (maxSize == 0)
    485                 maxSize = 64;
    486 
    487             bool readable = true;
    488             TextureImporterNPOTScale npotScale = TextureImporterNPOTScale.ToNearest;
    489             TextureWrapMode wrapMode = TextureWrapMode.Clamp;
    490             TextureImporterCompression compression = TextureImporterCompression.Uncompressed;
    491 
    492             bool changed = false;
    493 
    494             var importer = (TextureImporter)AssetImporter.GetAtPath(path);
    495             TextureImporterSettings settings = new TextureImporterSettings();
    496             importer.ReadTextureSettings(settings);
    497 
    498             settings.alphaIsTransparency = true;
    499             settings.mipmapEnabled = false;
    500 
    501             if (settings.readable != readable)
    502             {
    503                 settings.readable = readable;
    504                 changed = true;
    505             }
    506 
    507             if (settings.npotScale != npotScale)
    508             {
    509                 settings.npotScale = npotScale;
    510                 changed = true;
    511             }
    512 
    513             if (settings.wrapMode != wrapMode)
    514             {
    515                 settings.wrapMode = wrapMode;
    516                 changed = true;
    517             }
    518 
    519             if (importer.maxTextureSize != maxSize)
    520             {
    521                 importer.maxTextureSize = maxSize;
    522                 changed = true;
    523             }
    524 
    525             if (importer.textureCompression != compression)
    526             {
    527                 importer.textureCompression = compression;
    528                 changed = true;
    529             }
    530 
    531             // set platform overriten as false
    532             var androidSetting = importer.GetPlatformTextureSettings("Android");
    533             var iosSetting = importer.GetPlatformTextureSettings("iPhone");
    534             var pcSetting = importer.GetPlatformTextureSettings("Standalone");
    535             if (androidSetting.overridden)
    536             {
    537                 androidSetting.overridden = false;
    538                 changed = true;
    539             }
    540             if (iosSetting.overridden)
    541             {
    542                 iosSetting.overridden = false;
    543                 changed = true;
    544             }
    545             if (pcSetting.overridden)
    546             {
    547                 pcSetting.overridden = false;
    548                 changed = true;
    549             }
    550             importer.SetPlatformTextureSettings(androidSetting);
    551             importer.SetPlatformTextureSettings(iosSetting);
    552             importer.SetPlatformTextureSettings(pcSetting);
    553 
    554             if (changed)
    555             {
    556                 importer.SetTextureSettings(settings);
    557                 AssetDatabase.ImportAsset(path);
    558             }
    559         }
    560 
    561     }
    562 }
    ParticleSystemCombiner

    加载的代码:

    1 using UnityEngine;
    2 
    3 public partial class ParticleLoader : MonoBehaviour
    4 {
    5     public string TextureName;
    6     public string ShaderName;
    7 }
    ParticleLoader
      1 using Common;
      2 using UnityEngine;
      3 
      4 public partial class ParticleLoader : MonoBehaviour
      5 {
      6     static ParticleAtlases s_atlases;
      7 
      8 
      9     // 加载图集
     10     public static void Initialize()
     11     {
     12         BundleLoader.Singleton.LoadAssetBundle("atlases/particlesystematlas.u", r =>
     13         {
     14             GameObject[] objs = r.Bundle.LoadAllAssets<GameObject>();
     15             s_atlases = objs[0].GetComponent<ParticleAtlases>();
     16         });
     17     }
     18 
     19     void OnEnable()
     20     {
     21         Load();
     22     }
     23 
     24     void Load()
     25     {
     26         ParticleSystemRenderer renderer = GetComponent<ParticleSystemRenderer>();
     27         if (!renderer)
     28             return;
     29 
     30         ParticleAtlases.Atlas targetAtlas = null;
     31         ParticleAtlases.TextureItem targetTextureConfig = null;
     32 
     33         // 找对应的配置
     34         for (int i = 0; i < s_atlases.Atlases.Length; i++)
     35         {
     36             ParticleAtlases.Atlas atlasData = s_atlases.Atlases[i];
     37             for (int j = 0; j < atlasData.Textures.Length; j++)
     38             {
     39                 ParticleAtlases.TextureItem textureData = atlasData.Textures[j];
     40                 if (textureData.Name == this.TextureName && textureData.ShaderName == this.ShaderName)
     41                 {
     42                     targetAtlas = atlasData;
     43                     targetTextureConfig = textureData;
     44                     break;
     45                 }
     46             }
     47 
     48             if (targetAtlas != null)
     49                 break;
     50         }
     51 
     52         if (targetAtlas != null && targetTextureConfig != null)
     53         {
     54             ParticleSystem ps = GetComponent<ParticleSystem>();
     55 
     56             renderer.sharedMaterial = targetAtlas.Material;             // 渲染
     57 
     58             SetTextureSheet(ps, targetTextureConfig);                   // 设置格子
     59 
     60             SetStartColor(ps, renderer, targetTextureConfig.Color);     // 设置颜色
     61 
     62             SetDepth(renderer, targetTextureConfig);                    // 排序
     63         }
     64     }
     65 
     66     // 设置格子
     67     void SetTextureSheet(ParticleSystem ps, ParticleAtlases.TextureItem targetTextureConfig)
     68     {
     69         var tsa = ps.textureSheetAnimation;
     70         float curveConstant = (float)targetTextureConfig.Index / targetTextureConfig.NumTilesX / targetTextureConfig.NumTilesY;
     71         tsa.enabled = true;
     72         tsa.numTilesX = targetTextureConfig.NumTilesX;
     73         tsa.numTilesY = targetTextureConfig.NumTilesY;
     74         tsa.animation = ParticleSystemAnimationType.WholeSheet;
     75         tsa.startFrame = new ParticleSystem.MinMaxCurve(0);
     76         tsa.frameOverTime = new ParticleSystem.MinMaxCurve(curveConstant);
     77         tsa.cycleCount = 1;
     78     }
     79 
     80     // 设置颜色
     81     void SetStartColor(ParticleSystem ps, ParticleSystemRenderer renderer, Color matColor)
     82     {
     83         var main = ps.main;
     84         switch (main.startColor.mode)
     85         {
     86             case ParticleSystemGradientMode.Color:
     87             case ParticleSystemGradientMode.Gradient:
     88             case ParticleSystemGradientMode.RandomColor:
     89             case ParticleSystemGradientMode.TwoGradients:
     90                 var targetColor = main.startColor.color * matColor;
     91                 main.startColor = new UnityEngine.ParticleSystem.MinMaxGradient(targetColor);
     92                 break;
     93 
     94             case ParticleSystemGradientMode.TwoColors:
     95                 var colorMin = main.startColor.colorMin * matColor;
     96                 var colorMax = main.startColor.colorMax * matColor;
     97                 main.startColor = new UnityEngine.ParticleSystem.MinMaxGradient(colorMin, colorMax);
     98                 break;
     99 
    100             default:
    101                 Debug.LogError("Unknown mode: " + main.startColor.mode);
    102                 break;
    103         }
    104 
    105         renderer.sharedMaterial.SetColor("_TintColor", Color.white);
    106     }
    107 
    108     // 排序
    109     void SetDepth(ParticleSystemRenderer renderer, ParticleAtlases.TextureItem targetTextureConfig)
    110     {
    111         int depth = targetTextureConfig.Depth;
    112         if (depth > 0 && renderer.sharedMaterial.renderQueue < depth)
    113             renderer.sharedMaterial.renderQueue = depth;
    114     }
    115 
    116 }
    ParticleLoader

     合并后的图集如下:

     合并后的粒子如下:

    效果如下:

  • 相关阅读:
    [Vue音乐项目] 第六节 歌单列表
    [Vue音乐项目] 第五节 服务器代理跨域
    [Vue音乐项目] 第四节 轮播图
    [Vue音乐项目] 第三节 JSONP跨越
    [Vue音乐项目] 第二节 前提工作
    [Vue音乐项目] 第一节 环境搭建
    HTML网页页脚版权标志
    移动端页面隐藏滚动条
    FDD项目中的总结
    bootstrap模态窗字体模糊
  • 原文地址:https://www.cnblogs.com/jietian331/p/8625078.html
Copyright © 2011-2022 走看看