PetViewSystem.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. --[[
  2. @ 宠物 需要在预览和战斗中显示的 内容
  3. viewDatas = {
  4. [Enum.HeroExtGoesShowType.God_Art] = {prefabGo = GameObject, prefabPath = String}
  5. }
  6. ]]
  7. local PetViewSystem = class("PetViewSystem")
  8. local ViewSystem = require("ViewSystem")
  9. local MultiTypeAssetLoadSystem = require("MultiTypeAssetLoadSystem")
  10. local AnimatorType = typeof(UnityEngine.Animator)
  11. local CfgMgr = ManagerContainer.CfgMgr
  12. local function CombineDiff(map, key, value, diffMap)
  13. if not key then
  14. return false
  15. end
  16. if not map or map[key] ~= value then
  17. diffMap[key] = value
  18. return true
  19. end
  20. return false
  21. end
  22. local function GetAnimatorControllerPath(cfgId, inEnvType)
  23. local petCfg = ManagerContainer.CfgMgr:GetPetDataById(cfgId)
  24. if not petCfg then
  25. return Constants.AnimatorPath, petCfg.BattleCtrl
  26. end
  27. if Enum.RoleInEnvType.PetLvUp == inEnvType then
  28. return Constants.AnimatorPath, petCfg.ShowCtrl
  29. else
  30. return Constants.AnimatorPath, petCfg.ShowCtrl
  31. end
  32. end
  33. function PetViewSystem:ctor()
  34. self.viewSystem = nil
  35. self.param = nil
  36. -- 实例化的对象,在系统销毁时,需要销毁或回收
  37. self.gameObject = nil
  38. -- 在异步创建中的扩展物件数据
  39. self.updateDiffExtSkins = nil
  40. -- 当前显示的扩展物件数据
  41. self.oldExtSkins = nil
  42. -- 如果不为空,说明基本骨骼都需要改变,则全部重新创建
  43. self.updatePetCfgId = nil
  44. self.oldPetCfgId = nil
  45. -- 在异步创建中的动作控制器
  46. self.updateInEnvType = nil
  47. -- 在异步创建中的额外显示数据
  48. self.updateExtGoesShow = nil
  49. -- 当前额外显示数据
  50. self.oldShowData = nil
  51. -- 当前显示的动作控制器
  52. self.oldInEnvType = nil
  53. self.ownercb = nil
  54. self.cb = nil
  55. self.loadSystem = MultiTypeAssetLoadSystem:new()
  56. self.loadSystem:SetCompleteCB(self, self.PreloadedAssets)
  57. end
  58. function PetViewSystem:Dispose()
  59. self:Recycle()
  60. self.loadSystem:Dispose()
  61. self.loadSystem = nil
  62. end
  63. function PetViewSystem:SetParam(param)
  64. self.param = param
  65. end
  66. function PetViewSystem:RefreshData(inEnvType, cfgId, extGoesShowData, createdOwner, createdCB)
  67. -- 角色模型已经生成成功了
  68. local viewChanged = false
  69. if not tolua.isnull(self.gameObject) and self.oldPetCfgId == cfgId then
  70. viewChanged = self:UpdateHeroExtGoesShowView(extGoesShowData)
  71. else
  72. self:Recycle()
  73. self:UpdateHeroExtGoesShowView(extGoesShowData)
  74. self.updatePetCfgId = cfgId
  75. viewChanged = true
  76. end
  77. if viewChanged then
  78. self.loadSystem:Cancel()
  79. self.updateInEnvType = inEnvType;
  80. self.ownercb = createdOwner
  81. self.cb = createdCB
  82. self:RefreshLoadSystem()
  83. end
  84. return viewChanged
  85. end
  86. --- 刷新显示数据,并自动变更形象
  87. function PetViewSystem:RefreshView(inEnvType, petCfgId, heroViewData, createdOwner, createdCB)
  88. -- 角色模型已经生成成功了
  89. local changed = self:RefreshData(inEnvType, petCfgId, heroViewData, createdOwner, createdCB)
  90. if not changed then
  91. if createdOwner and createdCB then
  92. createdCB(createdOwner, self.gameObject,false,self.param)
  93. end
  94. self.ownercb = nil
  95. self.cb = nil
  96. return
  97. end
  98. self:BeginCreate()
  99. end
  100. --- 获得预加载的资源列表 table(reousrceType, table(path))
  101. function PetViewSystem:StatisticsPreloadAssets(multiTypeAssetLoadSystem)
  102. if not multiTypeAssetLoadSystem then multiTypeAssetLoadSystem = MultiTypeAssetLoadSystem:new() end
  103. self.loadSystem:AddToLoadSystem(multiTypeAssetLoadSystem)
  104. end
  105. function PetViewSystem:RefreshLoadSystem()
  106. self.loadSystem:RemoveLoadAllAsset()
  107. local assetPath = nil
  108. local assetName = nil
  109. local cfgMgr = ManagerContainer.CfgMgr
  110. -- 基本骨骼
  111. if self.updatePetCfgId then
  112. local petCfg = cfgMgr:GetPetDataById(self.updatePetCfgId)
  113. if petCfg == nil then
  114. LogError(self.curLoadCfgId .. "isnt exist in PetCfg")
  115. return
  116. end
  117. local avatarData = ManagerContainer.CfgMgr:GetAvatarCfgById(petCfg.AvatarId)
  118. if avatarData == nil then
  119. LogError(roleCfg.AvatarId .. "isnt exist in AvatarCfg")
  120. return
  121. end
  122. self.loadSystem:AddLoadAsset(Enum.ResourceType.GameObject, Constants.ModelPath, avatarData.AvatarPrefab)
  123. end
  124. -- 动作控制器
  125. if self.updateInEnvType then
  126. assetPath, assetName = GetAnimatorControllerPath(self.updatePetCfgId or self.oldPetCfgId, self.updateInEnvType)
  127. self.loadSystem:AddLoadAsset(Enum.ResourceType.AnimatorController, assetPath, assetName)
  128. end
  129. if self.updateExtGoesShow then
  130. for heroViewType,val in pairs(self.updateExtGoesShow) do
  131. if heroViewType == Enum.HeroExtGoesShowType.Pet_Qiyue then
  132. if val.cfgIds and #val.cfgIds > 0 then
  133. for i = 1, #val.cfgIds do
  134. local cfgId = val.cfgIds[i]
  135. local petCfgData = CfgMgr:GetPetDataById(cfgId)
  136. if petCfgData then
  137. local natureData = CfgMgr:GetNatureDataById(petCfgData.NatureType)
  138. if natureData then
  139. local avatarPrefab = natureData.PetContract
  140. if avatarPrefab and avatarPrefab ~= '' then
  141. self.loadSystem:AddLoadAsset(Enum.ResourceType.GameObject, Constants.EffectPath, avatarPrefab)
  142. end
  143. end
  144. end
  145. end
  146. end
  147. end
  148. end
  149. end
  150. end
  151. ---@generic 预加载的资源已加载完成
  152. function PetViewSystem:PreloadedAssets()
  153. self:Create()
  154. end
  155. function PetViewSystem:BeginCreate()
  156. self.loadSystem:Begin()
  157. end
  158. function PetViewSystem:CancelCreate()
  159. self.loadSystem:Cancel()
  160. self.updateExtGoesShow = nil
  161. self.updatePetCfgId = nil
  162. self.updateInEnvType = nil
  163. end
  164. function PetViewSystem:Recycle()
  165. self:CancelCreate()
  166. if self.viewSystem then
  167. self.viewSystem:Dispose()
  168. end
  169. self.viewSystem = nil
  170. if not tolua.isnull(self.gameObject) then
  171. local go = self.gameObject
  172. local animator = go:GetComponent(AnimatorType)
  173. animator.runtimeAnimatorController = nil
  174. local petCfg = ManagerContainer.CfgMgr:GetPetDataById(self.oldPetCfgId)
  175. if petCfg == nil then
  176. LogError(self.curLoadCfgId .. "isnt exist in PetCfg")
  177. return
  178. end
  179. local avatarData = ManagerContainer.CfgMgr:GetAvatarCfgById(petCfg.AvatarId)
  180. if avatarData == nil then
  181. LogError(roleCfg.AvatarId .. "isnt exist in AvatarCfg")
  182. return
  183. end
  184. ManagerContainer.ResMgr:RecycleGO(Constants.ModelPath, avatarData.AvatarPrefab, go)
  185. end
  186. self.gameObject = nil
  187. self.oldShowData = nil
  188. self.oldExtSkins = nil
  189. self.oldPetCfgId = nil
  190. self.oldInEnvType = nil
  191. self.ownercb = nil
  192. self.cb = nil
  193. end
  194. -- 需要预先加载好了资源
  195. function PetViewSystem:Create()
  196. local assetPath = nil
  197. local assetName = nil
  198. local newGO = nil
  199. local cfgMgr = ManagerContainer.CfgMgr
  200. local isLeader = false
  201. -- 基本骨骼
  202. if self.updatePetCfgId then
  203. local petCfg = cfgMgr:GetPetDataById(self.updatePetCfgId)
  204. if petCfg == nil then
  205. LogError(self.curLoadCfgId .. "isnt exist in PetCfg")
  206. return
  207. end
  208. local avatarData = ManagerContainer.CfgMgr:GetAvatarCfgById(petCfg.AvatarId)
  209. if avatarData == nil then
  210. LogError(roleCfg.AvatarId .. "isnt exist in AvatarCfg")
  211. return
  212. end
  213. newGO = ManagerContainer.ResMgr:GetGoFromPool(Constants.ModelPath, avatarData.AvatarPrefab)
  214. if ManagerContainer.LuaModelMgr and ManagerContainer.LuaModelMgr.ModelRoot then
  215. newGO.transform:SetParent(ManagerContainer.LuaModelMgr.ModelRoot.transform)
  216. else
  217. newGO.transform.parent = nil
  218. end
  219. newGO.transform.position = Vector3.zero;
  220. newGO.transform.rotation = Quaternion.identity;
  221. newGO:SetActive(true)
  222. self.oldPetCfgId = self.updatePetCfgId
  223. self.gameObject = newGO
  224. end
  225. -- 动作控制器 (在有BlendShape的SkinnedMeshRenderer之后加,否则Animator不生效BlendShape动画)
  226. if self.updateInEnvType then
  227. assetPath, assetName = GetAnimatorControllerPath(self.updatePetCfgId or self.oldPetCfgId, self.updateInEnvType)
  228. local animatorController = ManagerContainer.ResMgr:GetAsset(assetPath, assetName)
  229. local go = self.gameObject
  230. if not tolua.isnull(go) then
  231. local animator = go:GetComponent(AnimatorType)
  232. if tolua.isnull(animator) then
  233. animator = go:AddComponent(AnimatorType)
  234. end
  235. animator.runtimeAnimatorController = animatorController
  236. end
  237. self.oldInEnvType = self.updateInEnvType
  238. end
  239. -- 额外显示物件
  240. local oldShowData = self.oldShowData
  241. if not oldShowData then
  242. oldShowData = {}
  243. self.oldShowData = oldShowData
  244. end
  245. if not self.viewSystem then
  246. self.viewSystem = ViewSystem.new()
  247. end
  248. -- 刷新额外显示
  249. if self.updateExtGoesShow then
  250. self.viewSystem:UpdateView(self.gameObject.transform, oldShowData, self.updateExtGoesShow)
  251. end
  252. -- 更新完形象,清空队列中的数据
  253. self.updatePetCfgId = nil
  254. self.updateInEnvType = nil
  255. self.updateExtGoesShow = nil
  256. -- 回调
  257. if self.ownercb and self.cb then
  258. self.cb(self.ownercb, self.gameObject, (newGO ~= nil),self.Param)
  259. end
  260. self.ownercb = nil
  261. self.cb = nil
  262. return self.gameObject
  263. end
  264. function PetViewSystem:RolePlayAni(go, aniName)
  265. if tolua.isnull(go) then return end
  266. local animator = go:GetComponent(Enum.TypeInfo.Animator)
  267. if tolua.isnull(animator) then return end
  268. animator:Play(aniName)
  269. end
  270. function PetViewSystem:GetGameObject()
  271. return self.gameObject
  272. end
  273. ----------------------------------------------拓展物件----------------------------------------------
  274. local function ExtGoesShowUpdate(map, key, data, diffMap)
  275. if not key or not data then
  276. return false
  277. end
  278. diffMap[key] = data[key]
  279. if not map or map[key] ~= data[key] then
  280. return true
  281. end
  282. return false
  283. end
  284. local function HeroExtGoesShowViewUpdate(inEnvType, oldShowData, curExtGoesShow)
  285. local extGoesShow = {}
  286. local changed = false
  287. if ExtGoesShowUpdate(oldShowData, Enum.HeroExtGoesShowType.Pet_Qiyue, curExtGoesShow, extGoesShow) then
  288. changed = true
  289. end
  290. return changed, extGoesShow
  291. end
  292. function PetViewSystem:UpdateHeroExtGoesShowView(extGoesShow)
  293. local changed, viewUpdate = HeroExtGoesShowViewUpdate(self.updateInEnvType, self.oldShowData, extGoesShow)
  294. if changed then
  295. self.updateExtGoesShow = nil
  296. end
  297. self.updateExtGoesShow = viewUpdate
  298. return changed
  299. end
  300. -------------------------------------------------------------------------------------------------
  301. return PetViewSystem