コード例 #1
0
ファイル: ResourceLoader.cs プロジェクト: wuhuolong/MaxBooks
 /// <summary>
 /// 从cache中加载bundle
 /// </summary>
 private bool load_bundle_from_cache(string _bundle_path, List <BundleObject> _all_bundles)
 {
     if (bundleobj_cache_.is_in_cache(_bundle_path))
     {
         BundleObject bundle_object = bundleobj_cache_.get_bundle_object_from_cache(_bundle_path);
         if (!_all_bundles.Contains(bundle_object))
         {
             _all_bundles.Add(bundle_object);
             bundle_object.add_ref();//增加引用,防止在加载过程中被gc销毁
             //bundle_object.load_fbx_inf();//set the mesh info if this is a fbx info
         }
         return(true);
     }
     return(false);
 }
コード例 #2
0
ファイル: BundleObject.cs プロジェクト: wuhuolong/MaxBooks
        /// <summary>
        /// 加载DefaultRes
        /// </summary>
        private IEnumerator load_first_bundle()
        {
            // 使用LoadFromFileAsync进行加载(ios包内外均可使用,android必须拷贝到包外)
            bool   is_from_package = false;
            uint   file_offset     = 0;
            string bundle_url      = get_bundle_url(FIRST_INIT_BUNDLE, ref is_from_package, ref file_offset);

            bundle_url = CommonTool.WipeFileSprit(bundle_url);

            AssetBundle bundle = null;

            if (AuditManager.Instance.Open)
            {
                var request = AssetBundle.LoadFromFileAsync(bundle_url, 0, file_offset);
                yield return(request);

                bundle = request.assetBundle;
            }
            else
            {
                var request = AssetBundle.LoadFromFileAsync(bundle_url);
                yield return(request);

                bundle = request.assetBundle;
            }

            BundleObject bundle_object = new BundleObject(FIRST_INIT_BUNDLE, bundle);

            bundle_object.add_ref();
            put_bundle_object_to_cache(FIRST_INIT_BUNDLE, bundle_object);

#if UNITY_IPHONE
            // 在ios提审/内存小于1G时,不进行Shader的预加载
            if (AuditManager.Instance.Open || SystemInfo.systemMemorySize <= 1024)
            {
                yield break;
            }
#endif

            // 加载ShaderVariantCollection
            var load_request = bundle.LoadAllAssetsAsync(typeof(UnityEngine.ShaderVariantCollection));
            yield return(load_request);

            var load_asset = load_request.asset;
            if (load_asset != null)
            {
                Debug.Log("load shadervariantvollection succ.");

                // warmup
                var shader_varient = load_asset as UnityEngine.ShaderVariantCollection;
                if (!shader_varient.isWarmedUp)
                {
                    shader_varient.WarmUp();
                }

                // Shader变体存为静态变量
                var variant_info = MainGame.GetGlobalMono().gameObject.AddComponent <ShaderVariantInfo>();
                if (variant_info != null)
                {
                    variant_info.ShaderVariantUsed = shader_varient;
                }
            }
            else
            {
                Debug.Log("load shadervariantvollection failed !!!");
            }
        }
コード例 #3
0
ファイル: BundleObject.cs プロジェクト: wuhuolong/MaxBooks
 public void put_bundle_object_to_cache(string _path, BundleObject _bundle_object)
 {
     bundles_cache_.Add(_path, _bundle_object);
 }
コード例 #4
0
ファイル: ResourceLoader.cs プロジェクト: wuhuolong/MaxBooks
        private IEnumerator gc_coroutine()
        {
            float start_time = Time.unscaledTime;

            if (!bundleobj_cache_.is_first_resource_loaded() || is_gcing_)
            {
                yield break;
            }

            is_gcing_ = true;

            // GameObject被销毁时,要减少对应AssetObject的引用
            foreach (xc.Tuple <GameObject, AssetObject> item in dic_gameobj_asset_)
            {
                if (item.get_item1_ == null)
                {
                    item.get_item2_.decrence_ref();
                }
            }
            dic_gameobj_asset_.RemoveAll(item => item.get_item1_ == null);

            // 销毁场景相关引用计数已为0的AssetObject
            List <string> assets = assetobj_cache_.get_cache_asset_for_gc_names(true);

            foreach (string path in assets)
            {
                if (!asset_lock_.try_lock(path))
                {
                    yield return(StartCoroutine(asset_lock_.try_lock_croutine(path)));
                }
                assetobj_cache_.try_clean_noused_asset(path);
                asset_lock_.unlock(path);
            }

            // 销毁其他引用计数已为0的AssetObject
            assets = assetobj_cache_.get_cache_asset_for_gc_names(false);
            foreach (string path in assets)
            {
                if (!asset_lock_.try_lock(path))
                {
                    yield return(StartCoroutine(asset_lock_.try_lock_croutine(path)));
                }
                assetobj_cache_.try_clean_noused_asset(path);
                asset_lock_.unlock(path);
            }

            ResourceUtilEx.Instance.gc(0);

            // ResourceUtilEx调用gc后需要再次检查引用计数已为0的AssetObject
            assets = assetobj_cache_.get_cache_asset_for_gc_names(false);
            foreach (string path in assets)
            {
                if (!asset_lock_.try_lock(path))
                {
                    yield return(StartCoroutine(asset_lock_.try_lock_croutine(path)));
                }
                assetobj_cache_.try_clean_noused_asset(path);
                asset_lock_.unlock(path);
            }

            // 卸载引用计数为0的assetbundle
            List <string> destroyed   = new List <string>();
            List <string> bundles_set = bundleobj_cache_.get_bundles_for_gc();

            foreach (string path in bundles_set)
            {
                if (!bundleobj_cache_.is_in_cache(path))
                {
                    continue;
                }
                if (!bundle_lock_.try_lock(path))
                {
                    yield return(StartCoroutine(bundle_lock_.try_lock_croutine(path)));
                }
                BundleObject bundle_object = bundleobj_cache_.get_bundle_object_from_cache(path);
                if (bundle_object.get_ref_count_ < 1)
                {
                    bundle_object.destroy();
                    bundleobj_cache_.remove_bundle_object_from_cache(path);
                }
                bundle_lock_.unlock(path);
            }

            SGameEngine.Pool <string> .List.Free(bundles_set);

#if UNITY_IPHONE
            // 1G内存的iphone设备开启gc
            if (SystemInfo.systemMemorySize <= 1024)
            {
                System.GC.Collect(0);
            }
#endif
            float mark_time = Time.unscaledTime;

            is_gcing_ = false;

            GameDebug.Log(string.Format("[ResourceLoader](gc_process)use time: {0}, mark time: {1}", Time.unscaledTime - start_time, Time.unscaledTime - mark_time));
        }
コード例 #5
0
ファイル: ResourceLoader.cs プロジェクト: wuhuolong/MaxBooks
        /// <summary>
        /// <para>加载UnityEngine.Object资源,资源不再使用后要调用AssetResource.Destroy()来销毁</para>
        /// <para>_asset_path:资源路径,eg: "Assets/Res/DefaultRes.prefab"</para>
        /// <para>_type:加载资源的类型</para>
        /// <para>_result:协程结束后返回加载资源的结果</para>
        /// <para>_lock_asset:为避免其他协程加载资源,是否进行锁定操作</para>
        /// <para>_scene_asset:是否是场景资源</para>
        /// <para>_scene_name:场景资源的名字</para>
        /// </summary>
        public IEnumerator load_asset(string _asset_path, Type _type, AssetResource _result, bool _lock_asset = true, bool _scene_asset = false, string _scene_name = "")
        {
            if (is_destroyed_)
            {
                yield break;
            }

            bool is_ui_asset = _asset_path.Contains("Assets/Res/UI");

            if (Const.Language != LanguageType.SIMPLE_CHINESE)
            {
                LocalizeManager.Instance.LocalizePath(ref _asset_path);
            }

#if UNITY_EDITOR
            // 在编辑器下检查资源是否添加到打包配置中(因为lightmap的bug,.unity3d场景暂时不进行资源检查)
            if (!CheckAssetCfged(_asset_path))
            {
                Debug.LogError(string.Format("asset {0} is not configured for bundle, load failed!", _asset_path));
                yield break;
            }
#endif

            if (_result.get_obj() != null)
            {
                Debug.LogError("resused an old assetresoure! you should create a new!");
                yield break;
            }
            //1. 等待first res加载完毕,其中包含bundleinfo
            while (!bundleobj_cache_.is_first_resource_loaded())
            {
                yield return(new WaitForEndOfFrame());
            }
            loading_ = true;

            // 检查资源对应的分包是否已经下载完毕
            int patch_id;
            if (!xpatch.XPatchManager.Instance.IsAssetDownloaded(_asset_path, out patch_id))
            {
                Debug.Log(string.Format("asset {0} is not download for bundle!", _asset_path));
                yield break;
            }

            //2. 锁定资源,避免加载同一份asset
            IEnumerator ielock = null;
            if (_lock_asset)
            {
                if (!asset_lock_.try_lock(_asset_path))
                {
                    ielock = asset_lock_.try_lock_croutine(_asset_path);
                    coroutine_locked_assets_.Add(ielock, _asset_path);
                    yield return(StartCoroutine(ielock));
                }
            }

            //3. 检查Cache中是否已经有对应的bundle,否则需要进行加载
            AssetObject found_obj = assetobj_cache_.get_from_cache(_asset_path);
            if (found_obj != null)
            {
                _result.set_obj(found_obj);
                if (_scene_asset)
                {
                    //load level
                    sceneLoadAsyncOp = SceneManager.LoadSceneAsync(_scene_name);
                    yield return(sceneLoadAsyncOp);
                }
            }
            else
            {
#if UNITY_EDITOR
                if (!EnableBundleInEditor)
                {
                    //editor enviroment
                    yield return(StartCoroutine(load_asset_from_assetdatabase(_asset_path, _type, _result, _lock_asset, _scene_asset, _scene_name)));
                }
                else
#endif
                {
                    //bundle enviroment
                    //4.从bundleinfo中获取asset的依赖项
                    AssetBundleInfoItem bundle_info = bundleobj_cache_.get_asset_bundle_info(_asset_path);
                    if (bundle_info == null)
                    {
                        Debug.LogError("Dynamic bundle not find!Editor path is " + _asset_path);
                        goto EXIT_LOAD_ASSET;
                    }
                    UnityEngine.Object  loaded_asset = null;
                    List <BundleObject> all_bundles  = new List <BundleObject>();

                    List <List <string> > sort_depends_list = bundleobj_cache_.get_asset_all_dependence(_asset_path);
                    foreach (List <string> sub_list in sort_depends_list)
                    {
                        // 先判断是否在Cache中
                        if (bundleobj_cache_.is_all_in_cache(sub_list))
                        {
                            foreach (string path in sub_list)
                            {
                                load_bundle_from_cache(path, all_bundles);
                            }
                        }
                        else
                        {
                            List <string> fail_list = new List <string>();
                            yield return(StartCoroutine(try_load_bundle_list_coroutine(sub_list, all_bundles, fail_list, is_ui_asset)));

                            //被其他协程锁定的bundle等待解锁后再进行加载
                            foreach (string depend_bundle_path in fail_list)
                            {
                                //lock
                                if (!bundle_lock_.try_lock(depend_bundle_path))
                                {
                                    yield return(StartCoroutine(bundle_lock_.try_lock_croutine(depend_bundle_path)));
                                }
                                //load bundle and add ref
                                if (!load_bundle_from_cache(depend_bundle_path, all_bundles))
                                {
                                    yield return(StartCoroutine(load_bundle_from_disk_coroutine(depend_bundle_path, all_bundles, is_ui_asset)));
                                }
                                //unlock
                                bundle_lock_.unlock(depend_bundle_path);
                            }
                        }
                    }

                    //5.锁定asset并进行加载
                    if (!bundle_lock_.try_lock(_asset_path))
                    {
                        yield return(StartCoroutine(bundle_lock_.try_lock_croutine(_asset_path)));
                    }
                    //load bundle and add ref
                    if (!load_bundle_from_cache(_asset_path, all_bundles))
                    {
                        yield return(StartCoroutine(load_bundle_from_disk_coroutine(_asset_path, all_bundles, is_ui_asset)));
                    }
                    //unlock
                    bundle_lock_.unlock(_asset_path);

                    if (all_bundles.Count < 1)
                    {
                        goto EXIT_LOAD_ASSET;
                    }

                    //6.从bundle中加载mainasset
                    // 在调用Bundle.Load()之前,需要将缓存所有的依赖bundle
                    if (!_scene_asset)
                    {
                        BundleObject root = all_bundles[all_bundles.Count - 1];
                        // 获取在bundle中的资源名字

                        /*string asset_name = root.get_asset_path_;
                         * int last_path_idx = asset_name.LastIndexOf('/');
                         * if(last_path_idx != -1)
                         *  asset_name = asset_name.Substring(last_path_idx + 1);
                         * last_path_idx = asset_name.LastIndexOf('.');
                         * if (last_path_idx != -1)
                         *  asset_name = asset_name.Substring(0, last_path_idx);*/

                        //loaded_asset = bundleobj_cache_.load_main_asset(root.get_asset_bundle_, _type, BundleNameDef.MAIN);
                        var loadReq = root.get_asset_bundle_.LoadAssetAsync(BundleNameDef.MAIN, _type);
                        yield return(loadReq);

                        loaded_asset = loadReq.asset;

                        if (loaded_asset == null)
                        {
                            Debug.LogError(string.Format("asset counld not be loaded {0} ,check xls or your project", _asset_path));
                            // 加载失败后要将依赖的bundle的引用计数减少
                            foreach (BundleObject bo in all_bundles)
                            {
                                bo.decrease_ref();// 因为load bundle的时候增加了引用计数,所以此处需要减少
                            }
                            goto EXIT_LOAD_ASSET;
                        }
                    }
                    // 场景资源在缓存bundle之后就可以使用
                    else
                    {
                        sceneLoadAsyncOp = SceneManager.LoadSceneAsync(_scene_name);
                        yield return(sceneLoadAsyncOp);
                    }

                    //7. 创建assetobject并添加到Cache中
                    AssetObject ao = _scene_asset ? new SceneAssetObject(_asset_path) : new AssetObject(_asset_path, loaded_asset);
                    foreach (BundleObject bo in all_bundles)
                    {
                        AssetBundleInfoItem bundle_item_depend = bundleobj_cache_.get_asset_bundle_info(bo.get_asset_path_);
                        bool shared = bundle_item_depend.shared;
                        // 当assetbundle不被多个资源引用时,可以立即将assetbundle的文件镜像卸载,并从Cache中清除
                        // Atlas经过特殊处理,虽然被多个资源引用,但是也会立即卸载

                        /// FIXME
                        /// 在2017版本中,此时unload assetbundle会报错

                        /*if(!shared)
                         * {
                         *  bo.destroy(false);
                         *  bundleobj_cache_.remove_bundle_object_from_cache(bo.get_asset_path_);
                         * }
                         * else*/
                        {
                            ao.add_depend_bundle(bo);
                        }
                        bo.decrease_ref();//decrease the ref added by load bundle
                    }
                    all_bundles.Clear();
                    assetobj_cache_.put_to_cache(_asset_path, ao);
                    _result.set_obj(ao);
                }
            }
            //9.unlock asset
EXIT_LOAD_ASSET:
            //unlock
            if (_lock_asset)
            {
                if (ielock != null)
                {
                    coroutine_locked_assets_.Remove(ielock);
                }
                asset_lock_.unlock(_asset_path);
            }

            loading_ = false;
        }
コード例 #6
0
ファイル: ResourceLoader.cs プロジェクト: wuhuolong/MaxBooks
        /// <summary>
        /// 从磁盘上加载bundle文件
        /// </summary>
        private IEnumerator load_bundle_from_disk_coroutine(string _bundle_path, List <BundleObject> _all_bundles, bool is_ui_asset)
        {
            // 获取实际的文件路径
            bool   from_install_package = false;
            uint   file_offset          = 0;
            string bundle_url           = bundleobj_cache_.get_bundle_url(_bundle_path, ref from_install_package, ref file_offset);

            if (bundle_url == null)
            {
                Debug.LogError(string.Format("[ResourceLoader](load_bundle_from_disk_coroutine)bundle url null. bundle path: {0}", _bundle_path));
                yield break;
            }

            AssetBundle bundle = null;

            if (from_install_package == false)// 在包外通过LoadFromFileAsync来加载会更快
            {
                bundle_url = CommonTool.WipeFileSprit(bundle_url);

                if (!is_ui_asset)
                {
                    if (AuditManager.Instance.Open) // 提审状态开启的时候,资源需要从bin文件读取
                    {
                        var requeset = AssetBundle.LoadFromFileAsync(bundle_url, 0, file_offset);
                        yield return(requeset);

                        bundle = requeset.assetBundle;
                    }
                    else
                    {
                        var requeset = AssetBundle.LoadFromFileAsync(bundle_url);
                        yield return(requeset);

                        bundle = requeset.assetBundle;
                    }
                }
                else
                {
                    if (AuditManager.Instance.Open) // 提审状态开启的时候,资源需要从bin文件读取
                    {
                        bundle = AssetBundle.LoadFromFile(bundle_url, 0, file_offset);
                    }
                    else
                    {
                        bundle = AssetBundle.LoadFromFile(bundle_url);
                    }
                }
            }
            else // 在包内时,因为程序修改了x.data的路径,所以必须通过www来进行加载*/
            {
#if UNITY_IPHONE
                if (AuditManager.Instance.Open) // 提审状态开启的时候,资源需要从bin文件读取
                {
                    // ios streamingasset目录下的文件也可以通过LoadFromFileAsync来读取
                    bundle_url = CommonTool.WipeFileSprit(bundle_url);
                    var requeset = AssetBundle.LoadFromFileAsync(bundle_url, 0, file_offset);
                    yield return(requeset);

                    bundle = requeset.assetBundle;
                }
                else
                {
                    // ios streamingasset目录下的文件也可以通过LoadFromFileAsync来读取
                    bundle_url = CommonTool.WipeFileSprit(bundle_url);
                    var requeset = AssetBundle.LoadFromFileAsync(bundle_url);
                    yield return(requeset);

                    bundle = requeset.assetBundle;
                }
#else
                // 通过www来加载bundle
                WWW www = new WWW(bundle_url);
                yield return(www);

                while (!www.isDone)
                {
                    Debug.LogError(string.Format("[ResourceLoader](load_bundle_from_disk_coroutine) this is harmless, bundle ids not donw after yield: {0}", _bundle_path));
                    yield return(new WaitForEndOfFrame());
                }
                // 加载完毕后获取assetbundle
                bundle = www.assetBundle;
                www.Dispose();
#endif
            }

            if (bundle == null)
            {
                string msg = string.Format("[ResourceLoader](load_bundle_from_disk_coroutine)load bundle from www failed, unity3d file is in valid, bundle path is {0} device is {1}", _bundle_path, SystemInfo.deviceModel);
                Debug.LogError(msg);
                ControlServerLogHelper.Instance.PostPlayerFollowRecord(PlayerFollowRecordSceneId.ResLoadFail, msg, false);
                // Post The File Msg To DownloadRepairer Manager
                //ClientEventMgr.GetInstance().FireEvent((int)ClientEvent.CE_BUNDLE_RES_LOAD_FAILED, new CEventBaseArgs(_bundle_path));
                var patch_mgr = xpatch.XPatchManager.Instance;
                if (patch_mgr.IsAutoFix)
                {
                    patch_mgr.DownloadBundle(_bundle_path);
                }

                BuglyAgent.ReportException(new IOException(), msg);

                yield break;
            }

            // 加载的bundle使用BundleObject进行包装并放入到Cache中
            BundleObject bundle_object = new BundleObject(_bundle_path, bundle);
            if (_bundle_path.EndsWith(CACHE_STR_CS))
            {
                bundle_object.add_ref();
            }
            bundleobj_cache_.put_bundle_object_to_cache(_bundle_path, bundle_object);
            _all_bundles.Add(bundle_object);
            bundle_object.add_ref();            //增加引用,防止在加载过程中被gc销毁
            //bundle_object.load_fbx_inf();//set the mesh info if this is a fbx info
        }
コード例 #7
0
ファイル: AssetObject.cs プロジェクト: wuhuolong/MaxBooks
 public void add_depend_bundle(BundleObject _bundle_object)
 {
     _bundle_object.add_ref();
     dependence_bundles_.Add(_bundle_object);
 }