Unity编辑器紫色

文章讲述了在Unity中如何解决由于平台差异导致的Shader兼容性问题,通过Shader.Find方法动态修改Shader,以及提供两种Shader添加方式:跟随AssetBundle和在Editor模式下运行。

紫色原因是因为编辑器内跑了其他平台的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

 

### Unity 编辑器启动后显示紫色屏幕的原因分析 当遇到Unity编辑器启动后呈现紫色屏幕的情况时,这通常是由图形驱动程序或显卡兼容性问题引起的。此外,也可能是由于某些特定设置不匹配所导致。 #### 可能原因一:DirectX版本不兼容 如果计算机上的DirectX版本过低,则可能导致渲染管线无法正常工作,进而使得窗口背景颜色默认为未初始化状态下的紫色[^1]。 #### 解决方案: 为了验证并解决问题,可以尝试调整项目中的Player Settings来强制使用较低级别的API: ```csharp // 打开Project Setting -> Player,在Other Settings下找到Graphics APIs选项, // 将其顺序更改为优先支持较老的API如OpenGL Core 或 D3D9。 ``` #### 可能原因二:VSync同步设置不当 垂直同步(VSync)功能可能会干扰帧缓冲区交换过程,特别是在多显示器环境下更容易出现问题。关闭此选项有助于排除潜在冲突。 #### 解决方法: 通过修改质量设置禁用V-Sync: ```csharp QualitySettings.vSyncCount = 0; // 关闭 VSync ``` 也可以考虑更新最新的显卡驱动程序以获得更好的稳定性和支持新特性。 #### 可能原因三:Shader编译错误或其他资源加载失败 有时着色器编译过程中产生的警告或错误不会立即显现出来,但在运行时却会影响整个场景的表现形式。特别是对于采用Forward+这样的高级光照模型而言更为敏感[^2]。 #### 处理措施: 检查控制台日志查看是否存在任何与材质、纹理有关联的问题报告;清理缓存重新导入所有资产文件确保它们都能被正确解析。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值