c1_lua/lua/app/common/spine_manager.lua
2025-05-13 00:11:35 +08:00

205 lines
6.9 KiB
Lua

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:loadUIHeroSpineWidgetAsync(name, parent, callback)
local path = string.format(HERO_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