自定义法线贴图(关闭unity法线贴图弹窗)

问题:

  • 工作需求需要自定义法线贴图alpha通道
  • 贴图格式选择了default
  • 但是unity会强制mark as normalmap

回溯源码:

  • 三个地方
  1. model导入的时候 ModelImporterPostProcessor
    InternalEditorUtility.PerformUnmarkedBumpMapTexturesFixing();
  2. MaterialEditor inspector面板
    CheckMaterial TextureCompatibilityWarning
  3. BumpMapSettingsFixingWindow

方案:

  1. 发帖
    https://forum.unity.com/threads/how-to-not-display-the-normalnap-settings-window-when-the-normal-map-is-set-to-default-type.886543/
  2. 代码操作
    将法线贴图修改模式改为静默模式
    继承AssetPostprocessor类
    重写OnPostprocessAllAssets 方法
    order设置为0(越小越优先)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditorInternal;
using UnityEngine;
namespace UnityEditor
{
    [InitializeOnLoad]
    public class EditingClass
    {
        // 启动将法线贴图修改模式改为静默模式
        static EditingClass()
        {
            Debug.LogError("Unity Awake !");
            Assembly asm = Assembly.Load("UnityEditor");
            Type testType = asm.GetType("UnityEditor.BumpMapSettings");

            foreach (var item in testType.GetProperties())
            {
                Debug.Log("silentMode" + item.GetValue(testType));
                if (item.Name.Equals("silentMode"))
                    item.SetValue(testType, true);
                Debug.Log("silentMode" + item.GetValue(testType));
            }
        }
    }

    public class MaterialProcess : AssetPostprocessor
    {
        public void OnPreprocessTexture()
        {
            Debug.LogError("pre" + assetPath);
            TextureImporter ti = TextureImporter.GetAtPath(assetPath) as TextureImporter;
            if (ti.normalmap && ti.DoesSourceTextureHaveAlpha())
            {
                ti.textureType = TextureImporterType.Default;
                Debug.LogError("assetPath " + assetPath);
            }
        }

        static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
        {
            foreach (var assetPath in importedAssets)
            {
                Debug.LogError("all " + assetPath);
                var isMaterialAsset = Path.GetExtension(assetPath) == ".mat";
                if (isMaterialAsset)
                {
                    // 材质球发生改变的时候,unity内部依然会检测法线贴图格式
                    var embeddedMaterials = AssetDatabase.LoadAllAssetsAtPath(assetPath).OfType<Material>();
                    foreach (var material in embeddedMaterials)
                    {
                        Shader shader = material.shader;
                        for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i)
                        {
                            if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
                            {
                                string propertyName = ShaderUtil.GetPropertyName(shader, i);
                                Texture tex = material.GetTexture(propertyName);
                                if (tex == null)
                                    continue;
                                string texPath = AssetDatabase.GetAssetPath(tex.GetInstanceID());
                                TextureImporter ti = TextureImporter.GetAtPath(texPath) as TextureImporter;
                                if (ti.normalmap && ti.DoesSourceTextureHaveAlpha())
                                {
                                    ti.textureType = TextureImporterType.Default;
                                    Debug.LogError("texPath " + texPath);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

然鹅。。。
上面的方法在2018适用
在2017不适用
最终暴力解决

  • 继承AssetPostprocessor类
  • 重写OnPostprocessAllAssets 方法
  • 反射获取BumpMapSettingsFixingWindow窗口类,在delaycall中 关掉它
private static void BumpMapWindowCheck(string[] assetpaths)
{
    if (null == assetpaths || assetpaths.Length == 0)
        return;

    EditorApplication.delayCall += AutoCloseBumpMapSettingWindow;
}

static void AutoCloseBumpMapSettingWindow()
{
    Assembly asm = Assembly.Load("UnityEditor");
    Type testType = asm.GetType("UnityEditor.BumpMapSettingsFixingWindow");
    UnityEngine.Object[] objectsOfTypeAll = UnityEngine.Resources.FindObjectsOfTypeAll(testType);
    EditorWindow editorWindow = objectsOfTypeAll.Length <= 0 ? (EditorWindow)null : objectsOfTypeAll[0] as EditorWindow;
    if (!(bool)((UnityEngine.Object)editorWindow))
        return;
    editorWindow.Close();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值