You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中Asset Bundle的Emission Map在移动端失效问题求助

Unity移动端Asset Bundle Emission Map失效问题解决

问题描述

我制作的包含Emission Map的Asset Bundle在Unity编辑器及桌面端运行完全正常,但打包到移动端后,Emission Map完全没有效果,其他功能均正常。以下是我的Asset Bundle构建代码:

using UnityEditor;
using System.IO;
using UnityEngine;

public class CreateAssetBundles {

    public static string assetBundleDirectory = "Assets/AssetBundles/";

    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles() {

        //if main directory doesnt exist create it
        if (Directory.Exists(assetBundleDirectory)) {
            Directory.Delete(assetBundleDirectory, true);
        }
        
        Directory.CreateDirectory(assetBundleDirectory);
        
        //create bundles for all platform (use IOS for editor support on MAC but must be on IOS build platform)
        BuildPipeline.BuildAssetBundles(assetBundleDirectory,BuildAssetBundleOptions.None, BuildTarget.iOS);
        AppendPlatformToFileName("IOS");
        Debug.Log("IOS bundle created...");

        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Android);
        AppendPlatformToFileName("Android");
        Debug.Log("Android bundle created...");

        RemoveSpacesInFileNames();

        AssetDatabase.Refresh();
        Debug.Log("Process complete!");
    }

    static void RemoveSpacesInFileNames() {
        foreach (string path in Directory.GetFiles(assetBundleDirectory)) {
            string oldName = path;
            string newName = path.Replace(' ', '-');
            File.Move(oldName, newName);
        }
    }

        static void AppendPlatformToFileName(string platform) {
        foreach (string path in Directory.GetFiles(assetBundleDirectory)) {
            //get filename
            string[] files = path.Split('/');
            string fileName = files[files.Length - 1];

            //delete files we dont need
            if (fileName.Contains(".") || fileName.Contains("Bundle")) {
                File.Delete(path);
            } else if (!fileName.Contains("-")){
                //append platform to filename
                FileInfo info = new FileInfo(path);
                info.MoveTo(path + "-" + platform);
            }
        }
    }
}

解决方法

1. 检查Shader与Material的Emission配置

  • 确认使用的Shader支持移动端Emission:比如Standard Shader要确保Emission选项已勾选,且Emission Color不为纯黑色(纯黑会被Unity自动禁用Emission)。
  • 手动启用Emission关键字:在Material的代码中添加material.EnableKeyword("_EMISSION");,确保移动端渲染时识别到发光属性。

2. 修正Asset Bundle构建代码的问题

你的构建代码中存在两个关键问题:

  • 误删必要文件:AppendPlatformToFileName方法删除了带"."的文件,这会删掉Asset Bundle的.manifest附属文件,导致资源加载时无法正确识别依赖。
  • 路径处理不跨平台:用Split('/')处理路径在Windows系统下会出错,建议改用Unity的Path类方法。

修改后的构建代码如下:

using UnityEditor;
using System.IO;
using UnityEngine;

public class CreateAssetBundles {

    public static string assetBundleDirectory = "Assets/AssetBundles/";

    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles() {

        if (Directory.Exists(assetBundleDirectory)) {
            Directory.Delete(assetBundleDirectory, true);
        }
        
        Directory.CreateDirectory(assetBundleDirectory);
        
        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.iOS);
        AppendPlatformToFileName(BuildTarget.iOS.ToString());
        Debug.Log("IOS bundle created...");

        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Android);
        AppendPlatformToFileName(BuildTarget.Android.ToString());
        Debug.Log("Android bundle created...");

        RemoveSpacesInFileNames();

        AssetDatabase.Refresh();
        Debug.Log("Process complete!");
    }

    static void RemoveSpacesInFileNames() {
        foreach (string path in Directory.GetFiles(assetBundleDirectory)) {
            string fileName = Path.GetFileName(path);
            if (fileName.Contains(" ")) {
                string newPath = Path.Combine(Path.GetDirectoryName(path), fileName.Replace(' ', '-'));
                File.Move(path, newPath);
            }
        }
    }

    static void AppendPlatformToFileName(string platform) {
        foreach (string path in Directory.GetFiles(assetBundleDirectory)) {
            string fileName = Path.GetFileName(path);
            // 仅处理主Asset Bundle文件,保留manifest文件
            if (!fileName.EndsWith(".manifest") && !fileName.Contains("-")) {
                string newPath = Path.Combine(Path.GetDirectoryName(path), $"{fileName}-{platform}");
                // 同步重命名对应的manifest文件
                string manifestPath = $"{path}.manifest";
                if (File.Exists(manifestPath)) {
                    string newManifestPath = $"{newPath}.manifest";
                    File.Move(manifestPath, newManifestPath);
                }
                File.Move(path, newPath);
            }
        }
    }
}

3. 移动端纹理与渲染设置检查

  • Emission Map压缩格式:在Texture Import Settings中,为移动端(iOS/Android)选择合适的压缩格式,比如ASTC(iOS)、ETC2(Android),避免使用桌面端的压缩格式导致纹理无法正确解析。
  • Quality Settings配置:在Edit > Project Settings > Quality中,切换到Mobile平台,确保Rendering Path为Forward或Deferred(部分低端机可能需要Forward,但要开启Emission支持),同时检查Allow HDR是否启用(发光效果依赖HDR)。
  • Lighting Settings:如果使用了烘焙GI,要确保Asset Bundle中的物体在构建前完成了光照烘焙;若使用实时GI,需在移动端开启实时GI支持。

4. 加载Asset Bundle后的验证

加载Asset Bundle后,手动检查Material的Emission属性:

// 加载Asset Bundle示例代码
AssetBundle bundle = AssetBundle.LoadFromFile(path);
GameObject obj = bundle.LoadAsset<GameObject>("YourObject");
Material mat = obj.GetComponent<Renderer>().material;
// 验证Emission是否启用
if (!mat.IsKeywordEnabled("_EMISSION")) {
    mat.EnableKeyword("_EMISSION");
}
// 确保Emission Color不为黑
if (mat.GetColor("_EmissionColor") == Color.black) {
    mat.SetColor("_EmissionColor", Color.white * 2f); // 示例:设置发光颜色
}

内容的提问来源于stack exchange,提问作者SRIVASTAVA PRAKHAR SUNIL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 08:36:13