• Unity3d+GameFramework:资源分析,资源依赖,循环依赖检测


    资源依赖

    在这里插入图片描述
    在这里插入图片描述

    先生成Resource

    根据ResourceCollection.xml

    Resource resource = Resource.Create(name, variant, fileSystem, loadType, packed, resourceGroups);
                m_Resources.Add(resource.FullName.ToLowerInvariant(), resource);
    
    • 1
    • 2

    增加打包资源:luoyikun/Cube1–>{“m_Assets”:[],“m_ResourceGroups”:[],“Name”:“luoyikun/Cube1”,“Variant”:null,“FullName”:“luoyikun/Cube1”,“AssetType”:0,“IsLoadFromBinary”:false,“FileSystem”:null,“LoadType”:0,“Packed”:false}
    增加打包资源:luoyikun/Cube2–>{“m_Assets”:[],“m_ResourceGroups”:[],“Name”:“luoyikun/Cube2”,“Variant”:null,“FullName”:“luoyikun/Cube2”,“AssetType”:0,“IsLoadFromBinary”:false,“FileSystem”:null,“LoadType”:0,“Packed”:false}

    再把asset塞入

    UnityGameFramework.Editor.ResourceTools.ResourceCollection.AssignAsset

    /// 
            /// 打某个asset 塞入bundle中
            /// 
            public bool AssignAsset(string guid, string name, string variant)
            {
            Asset asset = GetAsset(guid);
              
                if (asset == null)
                {
                    asset = Asset.Create(guid);
                    m_Assets.Add(asset.Guid, asset);
                }
                            resource.AssignAsset(asset, isScene);
            }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    bundle:luoyikun/Cube1中塞入asset->{“Guid”:“60a1645014198164680bd6871329b73b”,“Name”:“Assets/GameMain/luoyikun/Cube1.prefab”,“Resource”:null}
    bundle:luoyikun/Cube2中塞入asset->{“Guid”:“f0ce9e0e8a0456d4f992300134cfd602”,“Name”:“Assets/GameMain/luoyikun/Cube2.prefab”,“Resource”:null}

    生成依赖关系

    UnityGameFramework.Editor.ResourceTools.ResourceAnalyzerController.Analyze

     DependencyData dependencyData = new DependencyData();
                    AnalyzeAsset(assetName, assets[i], dependencyData, scriptAssetNames);
                    dependencyData.RefreshData(); 
                    PublicTools.DebugObj(dependencyData, "增加一条依赖关系:" + assetName + "-->");
                    
                    m_DependencyDatas.Add(assetName, dependencyData);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    增加一条依赖关系:Assets/GameMain/luoyikun/Cube1.prefab–>->{“m_DependencyResources”:[{“m_Assets”:[{“Guid”:“f0ce9e0e8a0456d4f992300134cfd602”,“Name”:“Assets/GameMain/luoyikun/Cube2.prefab”}],“m_ResourceGroups”:[],“Name”:“luoyikun/Cube2”,“Variant”:null,“FullName”:“luoyikun/Cube2”,“AssetType”:1,“IsLoadFromBinary”:false,“FileSystem”:null,“LoadType”:0,“Packed”:false}],“m_DependencyAssets”:[{“Guid”:“f0ce9e0e8a0456d4f992300134cfd602”,“Name”:“Assets/GameMain/luoyikun/Cube2.prefab”,“Resource”:{“m_Assets”:[],“m_ResourceGroups”:[],“Name”:“luoyikun/Cube2”,“Variant”:null,“FullName”:“luoyikun/Cube2”,“AssetType”:1,“IsLoadFromBinary”:false,“FileSystem”:null,“LoadType”:0,“Packed”:false}}],“m_ScatteredDependencyAssetNames”:[],“DependencyResourceCount”:1,“DependencyAssetCount”:1,“ScatteredDependencyAssetCount”:0}

    增加一条依赖关系:Assets/GameMain/luoyikun/Cube2.prefab–>->{“m_DependencyResources”:[{“m_Assets”:[{“Guid”:“60a1645014198164680bd6871329b73b”,“Name”:“Assets/GameMain/luoyikun/Cube1.prefab”}],“m_ResourceGroups”:[],“Name”:“luoyikun/Cube1”,“Variant”:null,“FullName”:“luoyikun/Cube1”,“AssetType”:1,“IsLoadFromBinary”:false,“FileSystem”:null,“LoadType”:0,“Packed”:false}],“m_DependencyAssets”:[{“Guid”:“60a1645014198164680bd6871329b73b”,“Name”:“Assets/GameMain/luoyikun/Cube1.prefab”,“Resource”:{“m_Assets”:[],“m_ResourceGroups”:[],“Name”:“luoyikun/Cube1”,“Variant”:null,“FullName”:“luoyikun/Cube1”,“AssetType”:1,“IsLoadFromBinary”:false,“FileSystem”:null,“LoadType”:0,“Packed”:false}}],“m_ScatteredDependencyAssetNames”:[],“DependencyResourceCount”:1,“DependencyAssetCount”:1,“ScatteredDependencyAssetCount”:0}

    循环依赖检测

    在这里插入图片描述

    循环引用解释

    在这里插入图片描述

    GameFrameworkException: Can not load dependency asset ‘Assets/GameMain/luoyikun/Cube2.prefab’ when load asset ‘Assets/GameMain/luoyikun/Cube1.prefab’.

    尝试在加载依赖时,已加载不放入任务

    在GameFramework.Resource.ResourceManager.ResourceLoader.LoadDependencyAsset

    List<LoadResourceTaskBase> listTask = new List<LoadResourceTaskBase>(8);
    m_TaskPool.GetAllTasks(listTask);
    bool isExist = false;
    GameFrameworkLog.Info("所有任务数量{0}", listTask.Count);
    for (int i = 0; i < listTask.Count; i++)
    {
        if (listTask[i].AssetName == assetName)
        {
            GameFrameworkLog.Info("所有任务中存在{0}", assetName);
            isExist = true;
            return true;                   
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    出现a等待b,b等待a,因为
    GameFramework.Resource.ResourceManager.ResourceLoader.LoadResourceAgent.Start

    //遍历依赖
                        foreach (string dependencyAssetName in m_Task.GetDependencyAssetNames())
                        {
                            //如果依赖asset不能spawn,接着等待
                            if (!m_ResourceLoader.m_AssetPool.CanSpawn(dependencyAssetName))
                            {
                                GameFrameworkLog.Info("{0}依赖项{1}未加载完成", m_Task.AssetName,dependencyAssetName);
                                m_Task.StartTime = default(DateTime);
                                return StartTaskStatus.HasToWait;
                            }
                        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    会互相等待依赖项加载完,所以cube1等待cube2,cube2等待cube1,不会执行下去

    循环检测

    UnityGameFramework.Editor.ResourceTools.ResourceAnalyzerController.CircularDependencyChecker

    foreach (string host in hosts) //主资源被引用情况
                    {
                        LinkedList<string> route = new LinkedList<string>();
                        HashSet<string> visited = new HashSet<string>();
                        if (Check(host, route, visited))
                        {
                            results.Add(route.ToArray());
                        }
                    }
                    
        private bool Check(string host, LinkedList<string> route, HashSet<string> visited)
                {
                    //把主资源,放入参观表,路径表
                    visited.Add(host);
                    route.AddLast(host);
    
                    foreach (Stamp stamp in m_Stamps)
                    {
                        if (host != stamp.HostAssetName) //只找当前host的依赖情况
                        {
                            GameFrameworkLog.Info("不是主资源名跳过{0}", host); 
                            continue;
                        }
    
                        //如果参观表包含了依赖 stamp的依赖
                        if (visited.Contains(stamp.DependencyAssetName))
                        {
                            //插入路径表最后项目返回
                            route.AddLast(stamp.DependencyAssetName);
                            return true;
                        }
    
                        //递归检查 当前stamp的依赖 b
                        if (Check(stamp.DependencyAssetName, route, visited))
                        {
                            return true;
                        }
                    }
    
                    //路径表移除最后一个
                    route.RemoveLast();
                    //参观表移除host
                    visited.Remove(host);
                    return false;
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在Stamps中存在循环引用的两对

    记录1
    "HostAssetName": "Assets/GameMain/luoyikun/Cube1.prefab",
            "DependencyAssetName": "Assets/GameMain/luoyikun/Cube2.prefab",
    
    记录2
    "HostAssetName": "Assets/GameMain/luoyikun/Cube2.prefab",
            "DependencyAssetName": "Assets/GameMain/luoyikun/Cube1.prefab",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. cube1放入visited,route中,挂起处1
    2. 遍历依赖对,递归调用,cube2放入visited ,route的最后
    3. 递归,遍历所有依赖对,cube2不是记录1的host,跳过记录1
    4. 来到记录2,此时visited包含了cube1,把cube1插入route的最后,,此时route 为 cube1,cube2,cube1返回true
    5. 再遍历记录2,依次找到循环
  • 相关阅读:
    SSM的技术论坛含前后台(游戏内容)
    网格布局grid
    react实战系列 —— 起步(mockjs、第一个模块、docusaurus)
    基于目标检测的无人机航拍场景下小目标检测实践
    软设上午题错题知识点4
    SpringBoot 集成Sa-Token 一个轻量级Java权限认证框架,让鉴权变得简单、优雅!
    【JavaScript】浏览器支持ES6和使用export import语法
    黏菌优化算法SMA(Matlab完整代码实现)
    【C++】STL — string的使用 + 模拟实现
    【C语言刷LeetCode】1592. 重新排列单词间的空格(E)
  • 原文地址:https://blog.csdn.net/luoyikun/article/details/125917224