Unity编辑器紫色

2023-12-26 15:30:13

紫色原因是因为编辑器内跑了其他平台的shader兼容性导致的,需要动态的去修改shader,主要用到Unity的api :?Shader.Find(shaderName);

具体的工具代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ShaderManager
{
    public static ShaderManager Instance;
    public static ShaderManager GetInstance()
    {
        if (Instance == null)
        {
            Instance = new ShaderManager();
        }
        return Instance;
    }
    List<Renderer> results = new List<Renderer>();
    List<Image> imageResults = new List<Image>();
    /// <summary>
    /// 修改一个AssetBundle内的所有shader
    /// </summary>
    public void ResetAllMaterials(AssetBundle bundle)
    {
        //对Material进行更改
        var materials = bundle.LoadAllAssets<Material>();
        foreach (Material m in materials)
        {
            var shaderName = m.shader.name;
            if (shaderName == "Hidden/InternalErrorShader")
                continue;
            var newShader = Find(shaderName);
            if (newShader != null)
            {
                m.shader = newShader;
            }
            else
            {
                Debug.LogWarning("unable to refresh shader: " + shaderName + " in material " + m.name);
            }
        }
        //对GameObject进行更改
        var gameObjects = bundle.LoadAllAssets<GameObject>();
        foreach (var go in gameObjects)
        {
            results.Clear();
            //物件上的材质
            go.GetComponentsInChildren<Renderer>(true, results);
            if (results.Count > 0)
            {
                for (int ii = 0; ii < results.Count; ii++)
                {
                    for (int k = 0; k < results[ii].sharedMaterials.Length; ++k)
                    {
                        var m = results[ii].sharedMaterials[k];
                        UseEditorShader(m);
                    }
                    //粒子
                    if (results[ii] is ParticleSystemRenderer particleRender)
                    {
                        UseEditorShader(particleRender.sharedMaterial);
                        UseEditorShader(particleRender.trailMaterial);
                    }
                }
            }
            //贴图上的材质
            imageResults.Clear();
            go.GetComponentsInChildren<Image>(true, imageResults);
            if (imageResults.Count > 0)
            {
                for (int ii = 0; ii < imageResults.Count; ii++)
                {
                    UseEditorShader(imageResults[ii].material);
                }
            }
        }
    }
    
    /// <summary>
    /// 修改单个物件的Shader
    /// </summary>
    /// <param name="go"></param>
    public void ResetEditorShader(GameObject go)
    {
        if (go == null)
        {
            return;
        }
        results.Clear();
        go.GetComponentsInChildren<Renderer>(true, results);
        if (results.Count > 0)
        {
            for (int ii = 0; ii < results.Count; ii++)
            {
                for (int k = 0; k < results[ii].sharedMaterials.Length; ++k)
                {
                    var m = results[ii].sharedMaterials[k];
                    UseEditorShader(m);
                }
            }
        }
    }
    void UseEditorShader(ref Shader shader)
    {
        if (shader == null)
            return;
        var shaderName = shader.name;
        var newShader = Find(shaderName);
        if (newShader != null)
            shader = newShader;
    }
    void UseEditorShader(Material material)
    {
        if (material == null || material.shader == null)
            return;
        var shaderName = material.shader.name;
        var newShader = Find(shaderName);
        if (newShader != null)
            material.shader = newShader;
    }
    Shader Find(string shaderName)
    {
        Shader outShader = Shader.Find(shaderName);
        if (outShader == null)
        {
            outShader = Shader.Find("Standard");
        }
        return outShader;
    }
}

Shader的添加形式大概有两种:

  1. 跟随AssetBundle 打进包里面,可以直接使用
    ? ? ?
    ShaderManager.GetInstance().ResetAllMaterials(bundleInfo.bundle);

  2. 自建材质
                material = new Material(shader);
    #if EDITOR_RUN_OTHER_PLAT
                material.shader = Shader.Find(material.shader.name);
    #endif

?

文章来源:https://blog.csdn.net/pdw_jsp/article/details/135222450
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。