local UISpineObject = require "app/bf/unity/ui_spine_object" local MeshSpineObject = require "app/bf/unity/mesh_spine_object" local CharacterSpineObject = require "app/bf/unity/character_spine_object" local SpineManager = { heroCacheList = {}, heroCacheMap = {}, battleCacheList = {}, battleCacheMap = {}, heroSpineAsset = {} } local TYPE_OF_GAME_OBJECT = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT local TYPE_OF_SPINE_ASSET = GConst.TYPEOF_UNITY_CLASS.SKELETON_DATA_ASSET local UI_SPINE_PREFAB_PATH = "assets/prefabs/spine/ui/ui_spine_obj.prefab" local MESH_SPINE_PREFAB_PATH = "assets/prefabs/spine/mesh/mesh_spine_obj.prefab" local UI_SPINE_ASSET_PATH = "assets/arts/spines/ui/%s/%s_skeletondata.asset" local MESH_SPINE_ASSET_PATH = "assets/arts/spines/mesh/%s/%s_skeletondata.asset" local HERO_SPINE_ASSET_PATH = "assets/arts/spines/characters/%s/%s_skeletondata.asset" local HERO_CACHE_SIZE = 10 -- 英雄缓存容量 local BATTLE_CACHE_SIZE = 30 -- 战斗特效缓存容量 ---- canvas renderer function SpineManager:loadUISpineWidgetAsync(name, parent, callback) local path = string.format(UI_SPINE_ASSET_PATH, name, name) ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset) if parent and parent:isDestroyed() then ResourceManager:unload(spineAssetPath) return end self:loadUISpinePrefabAsync(parent, spineAssetPath, spineAsset, callback) end) end function SpineManager:loadUISpinePrefabAsync(parent, spineAssetPath, spineAsset, callback) ResourceManager:loadAsync(UI_SPINE_PREFAB_PATH, TYPE_OF_GAME_OBJECT, function(prefabPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(spineAssetPath) ResourceManager:unload(prefabPath) return end local uiSpineObject = UISpineObject:create() uiSpineObject:initWithPrefab(UI_SPINE_PREFAB_PATH, prefab) uiSpineObject:getAnimationState() uiSpineObject:initSkeletonDataAsset(spineAsset) uiSpineObject:addUnloadCallback(function(obj) ResourceManager:unload(spineAssetPath) ResourceManager:unload(prefabPath) end) if parent then uiSpineObject:setParent(parent, false) end if callback then callback(uiSpineObject) end end) end function SpineManager:loadHeroAsync(id, parent, callback) local path = "assets/prefabs/spine/ui/characters/" .. id .. ".prefab" ResourceManager:loadAsync(path, TYPE_OF_GAME_OBJECT, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local characterObject = CharacterSpineObject:create() characterObject:initWithPrefab(assetPath, id, prefab) characterObject:addUnloadCallback(function(obj) local modelPath = obj:getAssetPath() if self.heroCacheMap[modelPath] then ResourceManager:unload(modelPath) else if #self.heroCacheList >= HERO_CACHE_SIZE then local headPath = table.remove(self.heroCacheList, 1) ResourceManager:unload(headPath) self.heroCacheMap[headPath] = nil end self.heroCacheMap[modelPath] = true table.insert(self.heroCacheList, modelPath) end end) if parent then characterObject:setParent(parent, false) end if callback then callback(characterObject) end end) end function SpineManager:loadHeroSpineAssetAsync(id, parent, callback) if self.heroSpineAsset[id] then callback(self.heroSpineAsset[id]) else local path = string.format(HERO_SPINE_ASSET_PATH, id, id) ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset) if parent and parent:isDestroyed() then ResourceManager:unload(spineAssetPath) return end if self.heroSpineAsset[id] then ResourceManager:unload(spineAssetPath) else self.heroSpineAsset[id] = spineAsset end callback(spineAsset) end) end end function SpineManager:loadBattleSpineAssetAsync(path, parent, callback) ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset) if parent and parent:isDestroyed() then ResourceManager:unload(spineAssetPath) return end callback(spineAssetPath, spineAsset) end) end function SpineManager:loadBattleEffectAsync(path, parent, callback) ResourceManager:loadAsync(path, TYPE_OF_GAME_OBJECT, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local spineObject = CharacterSpineObject:create() spineObject:initWithPrefab(assetPath, prefab) spineObject:addUnloadCallback(function(obj) local effectPath = obj:getAssetPath() if self.battleCacheMap[effectPath] then ResourceManager:unload(effectPath) else if #self.battleCacheList == BATTLE_CACHE_SIZE then local headPath = table.remove(self.battleCacheList, 1) ResourceManager:unload(headPath) self.battleCacheMap[headPath] = nil end self.battleCacheMap[effectPath] = true table.insert(self.battleCacheList, effectPath) end end) if parent then spineObject:setParent(parent, false) end if callback then callback(spineObject) end end) end ---- mesh renderer function SpineManager:loadMeshSpineAsync(name, parent, callback) local path = string.format(MESH_SPINE_ASSET_PATH, name, name) ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset) if parent and parent:isDestroyed() then ResourceManager:unload(spineAssetPath) return end self:loadMeshSpinePrefabAsync(parent, spineAssetPath, spineAsset, callback) end) end function SpineManager:loadMeshSpinePrefabAsync(parent, spineAssetPath, spineAsset, callback) ResourceManager:loadAsync(MESH_SPINE_PREFAB_PATH, TYPE_OF_GAME_OBJECT, function(prefabPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(spineAssetPath) ResourceManager:unload(prefabPath) return end local meshSpineObject = MeshSpineObject:create() meshSpineObject:initWithPrefab(MESH_SPINE_PREFAB_PATH, prefab) meshSpineObject:getAnimationState() meshSpineObject:initSkeletonDataAsset(spineAsset) meshSpineObject:addUnloadCallback(function(obj) ResourceManager:unload(spineAssetPath) ResourceManager:unload(prefabPath) end) if parent then meshSpineObject:setParent(parent, false) end if callback then callback(meshSpineObject) end end) end return SpineManager