local CharacterFSMManager = require "app/module/character_fsm/character_fsm_manager" local ModelObject = require "app/bf/unity/model_object" local CharacterObject = require "app/bf/unity/character_object" local WeaponObject = require "app/bf/unity/weapon_object" local ModelManager = { heroCacheList = {}, heroCacheMap = {} } local TypeOfGameObject = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT local HERO_CACHE_SIZE = 10 -- 英雄缓存容量 function ModelManager:loadHeroAsync(id, parent, weaponAniName, weapon, callback) local path = "assets/prefabs/models/characters/" .. id .. ".prefab" ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local characterObject = CharacterObject:create() characterObject:initWithPrefab(assetPath, prefab, id) 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 local fsm = CharacterFSMManager:getFsm(characterObject) characterObject:setCharacterFSM(fsm) local nodeName = "hand_r_weapon" if weapon then for k, name in pairs(GConst.HeroConst.WEAPON_NODE) do local find = string.find(weapon, k) if find then local node = characterObject:getBoneByName(name) if node then nodeName = name end break end end end if weapon and characterObject:getBoneByName(nodeName) then ModelManager:loadWeaponAsync(weapon, characterObject:getBoneByName(nodeName), function(weaponObj) if weaponObj then characterObject:setWeaponInfo(weaponAniName, weaponObj) end characterObject:play("idle") if callback then callback(characterObject, weaponObj) end end) else characterObject:play("idle") if callback then callback(characterObject) end end end) end function ModelManager:loadWeaponAsync(weapon, parent, callback) local path = "assets/prefabs/models/weapon/" .. weapon .. ".prefab" ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local modelObject = WeaponObject:create() modelObject:initWithPrefab(assetPath, prefab) modelObject:addUnloadCallback(function(obj) ResourceManager:unload(obj:getAssetPath()) end) if parent then modelObject:setParent(parent, false) end if callback then callback(modelObject) end end) end function ModelManager:loadMonsterAsync(id, parent, callback) local path = "assets/prefabs/models/characters/" .. id .. ".prefab" ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local characterObject = CharacterObject:create() characterObject:initWithPrefab(assetPath, prefab) characterObject:addUnloadCallback(function(obj) local modelPath = obj:getAssetPath() ResourceManager:unload(modelPath) end) if parent then characterObject:setParent(parent, false) end local fsm = CharacterFSMManager:getFsm(characterObject) characterObject:setCharacterFSM(fsm) if callback then callback(characterObject) end end) end function ModelManager:loadModelAsync(path, parent, callback) ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local modelObject = ModelObject:create() modelObject:initWithPrefab(assetPath, prefab) modelObject:addUnloadCallback(function(obj) ResourceManager:unload(obj:getAssetPath()) end) if parent then modelObject:setParent(parent, false) end if callback then callback(modelObject) end end) end function ModelManager:loadHeroShowAsync(id, parent, callback) local path = "assets/prefabs/models/characters_show/" .. id .. ".prefab" ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab) if parent and parent:isDestroyed() then ResourceManager:destroyPrefab(prefab) ResourceManager:unload(assetPath) return end local characterObject = CharacterObject:create() characterObject:initWithPrefab(assetPath, prefab, id) characterObject:addUnloadCallback(function(obj) ResourceManager:unload(obj:getAssetPath()) end) if parent then characterObject:setParent(parent, false) end local fsm = CharacterFSMManager:getFsm(characterObject) characterObject:setCharacterFSM(fsm) if callback then callback(characterObject) end end) end function ModelManager:getHeroModelPathById(id) return "assets/prefabs/models/characters/" .. id .. ".prefab" end function ModelManager:markCache(path) if #self.heroCacheList >= HERO_CACHE_SIZE then return false end if self.heroCacheMap[path] == nil then self.heroCacheMap[path] = true table.insert(self.heroCacheList, path) return true end return false end function ModelManager:isCacheFull() return #self.heroCacheList >= HERO_CACHE_SIZE end function ModelManager:clearCache() for _, path in ipairs(self.heroCacheList) do ResourceManager:unload(path) end self.heroCacheList = {} self.heroCacheMap = {} end return ModelManager