Unity 变体探秘

起因:我们在打Bundle 的时候出现了同一个AB里面有相同文件名字的文件(虽然路径不同),具体报错如下:

14:22:18 Building AssetBundle failed because hash collision was detected in the deterministic id generation.
14:22:18 Conflict happened between Asset "Assets/Game/GameAsset/RofConfig/HMT/RofBonus.json" and "Assets/Game/GameAsset/RofConfig/SEA/RofBonus.json

上面报错的两个文件可以看到是文件名相同,文件夹相同
 
我们代码里面打包的代码如下,会发现我们指定了变体Variant值,


        assetBundleBuilds.Add(new AssetBundleBuild()
        {
            assetBundleName = "Data",
            assetBundleVariant = "Summer",
            ......

同时打包的参数是用的Hash值
 

  var options =
                BuildAssetBundleOptions.DeterministicAssetBundle |
                BuildAssetBundleOptions.StrictMode |
                BuildAssetBundleOptions.ChunkBasedCompression;

Unity API 解释,这里的Hash值居然是根据文件名字生成的,而不是meta 里面的hash值(开始在这里也掉坑了),真奇葩的设定

  //
        // 摘要:
        //     Builds an asset bundle using a hash for the id of the object stored in the asset
        //     bundle.
        DeterministicAssetBundle = 16,

所以就会出现开始的虽然在不同的文件夹下也会报错提示Hash冲突的情况了。

这里研究下变体的运行原理

打包,场景下依赖其中的某个变体Data.Spring ,如下有三个变体 Data.Spring ; Data.Summer; Data.Fall ,打包代码如下

#if UNITY_EDITOR
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class Build
{
    [MenuItem("Tools/Build")]
	static void PlatformBuild()
    {
        Caching.ClearCache();
        var assetBundleBuilds = new List<AssetBundleBuild>();
        assetBundleBuilds.Add(new AssetBundleBuild()
        {
            assetBundleName = "Level",
            assetBundleVariant = "",
            assetNames = new string[] {
                "Assets/Level.unity",
            },
        });

        assetBundleBuilds.Add(new AssetBundleBuild()
        {
            assetBundleName = "Data1",
            assetBundleVariant = "Spring",
            assetNames = new string[] {
                "Assets/Data/Spring/Main.jpg",
                "Assets/Data/Spring/Text.prefab",
                "Assets/Data/Spring/String.txt",
                "Assets/Data/Spring/Color.asset",
            },
        });
        
        assetBundleBuilds.Add(new AssetBundleBuild()
        {
            assetBundleName = "Data",
            assetBundleVariant = "Fall",
            assetNames = new string[] {
               "Assets/Data/Fall/Text.prefab",
               "Assets/Data/Fall/Main.jpg",
               "Assets/Data/Fall/String.txt",
               "Assets/Data/Fall/Color.asset",
            },
        });

        assetBundleBuilds.Add(new AssetBundleBuild()
        {
            assetBundleName = "Data",
            assetBundleVariant = "Summer",
            assetNames = new string[] {
                "Assets/Data/Summer/Main.jpg",
                "Assets/Data/Summer/Text.prefab",
                "Assets/Data/Summer/String.txt",
                "Assets/Data/Summer/Color.asset",
            },
        });

        var path = Path.GetFullPath(Application.dataPath + "/../Build");
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        BuildPipeline.BuildAssetBundles(path,
            assetBundleBuilds.ToArray(), 
            BuildAssetBundleOptions.ForceRebuildAssetBundle,
            BuildTarget.StandaloneWindows64);

        if (!UnityEditorInternal.InternalEditorUtility.inBatchMode)
        {
            System.Diagnostics.Process.Start(path);
        }
    }
}
#endif

加载,通过Theme切换不同场景变体,会发现我们怎么切换都能加载到争取的资源

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Loader : MonoBehaviour {

    public enum Theme
    {
        Spring,
        Fuck,
        Summer
    }

    public Theme loadTheme = Theme.Spring;
    IEnumerator Start()
    {
        var root = Application.dataPath + "/../Build";
        var themePath = root + "/data." + loadTheme.ToString().ToLower();
        var levelPath = root + "/level";

        var ab = AssetBundle.LoadFromFile(themePath);
        foreach (var assetName in ab.GetAllAssetNames())
        {
            Debug.LogFormat("Assets: {0}", assetName);
        }

        AssetBundle.LoadFromFile(levelPath);
        yield return SceneManager.LoadSceneAsync("Level", LoadSceneMode.Additive);
    }
}

我们截取打包的AB进行分析 level.manifest 依赖关系如下,可以看到Level 依赖的是data.spring 这个AB

Assets:
- Assets/Level.unity
Dependencies:
- C:/Users/Admin/Desktop/Unity-AssetBundleVariantsExample-master/Build/data.spring

当我们切换到其他枚举去加载的时候同样可以很正确的加载到资源,那么引擎是怎么能找到这个正确的Data.Fall  或者 Data.Summer 的AB的呢?** 答案是变体的内部唯一值是相同的 ** 

所以在我们加载的时候就能正确找到对应的资源了

 

 

 

 

 

 

 

 

 

 

原文地址:https://blog.csdn.net/pdw_jsp/article/details/114407445

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要介绍了Unity游戏开发中外观模式是什么意思,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
这篇文章主要介绍Unity中地面检测方案的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.普通射线在角色坐标(一般是脚底)...
这篇文章主要介绍了Unity游戏开发中如何消除不想要的黄色警告,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带...
这篇文章主要介绍了Unity中有多少种渲染队列,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解
这篇文章主要介绍Unity中如何实现Texture,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!了解Texture2D 如上图,Texture2D是一张
小编给大家分享一下Unity中DOTS要实现的特点有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让...
这篇文章给大家分享的是有关unity中如何实现UGUI遮罩流光特效的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。下面是核心shader:Sh...
这篇文章主要为大家展示了“Unity中如何实现3D坐标转换UGUI坐标”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下...
这篇文章主要介绍了Unity游戏开发中设计模式的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
这篇文章主要介绍了Unity中如何实现仿真丝袜渲染,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了...
这篇文章给大家分享的是有关Unity插件OVRLipSync有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。项目需要接入对话口型动...
这篇文章主要介绍了Unity性能优化之DrawCall的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
这篇文章给大家分享的是有关Unity给力插件之Final IK怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。这插件有什么用:一般游...
这篇文章给大家分享的是有关Unity中如何内嵌网页插件UniWebView的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、常见Unity中内...
小编给大家分享一下Unity如何做流体物理的几个轮子,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让...
小编给大家分享一下Unity中Lod和Occlusion Culling的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收...
这篇文章将为大家详细讲解有关Unity中LineRenderer与TrailRenderer有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获...
这篇文章主要介绍了Unity中coroutine问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起...
这篇文章将为大家详细讲解有关unity中spine怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。骨骼动画首先我们来看到...
这篇文章主要为大家展示了“Unity Shader后处理中如何实现简单均值模糊”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学...