diff --git a/lua/app/bf/unity/character_spine_object.lua b/lua/app/bf/unity/character_spine_object.lua index 7f443044..da18aaa6 100644 --- a/lua/app/bf/unity/character_spine_object.lua +++ b/lua/app/bf/unity/character_spine_object.lua @@ -254,7 +254,6 @@ end function CharacterSpineObject:onDestroy() self:removeAnimationCompleteCallback() BaseObject.onDestroy(self) - self.skeletonAnimation = nil self.animationState = nil end diff --git a/lua/app/global/global_const.lua b/lua/app/global/global_const.lua index c2dee294..9d79bb20 100644 --- a/lua/app/global/global_const.lua +++ b/lua/app/global/global_const.lua @@ -110,6 +110,7 @@ GConst.TYPEOF_UNITY_CLASS = { SKELETON_ANIMATION = typeof(CS.Spine.Unity.SkeletonAnimation), SKELETON_DATA_ASSET = typeof(CS.Spine.Unity.SkeletonDataAsset), BONE_FOLLOWER = typeof(CS.Spine.Unity.BoneFollower), + BONE_FOLLOWER_GRAPHIC = typeof(CS.Spine.Unity.BoneFollowerGraphic), -- 自定义组件 MONKEY_POST = typeof(CS.MonkeyPost), CLOUD_CONTROL = typeof(CS.CloudControl), diff --git a/lua/app/module/battle/battle_const.lua b/lua/app/module/battle/battle_const.lua index c84eb200..f11a0599 100644 --- a/lua/app/module/battle/battle_const.lua +++ b/lua/app/module/battle/battle_const.lua @@ -18,6 +18,7 @@ BattleConst.SKILL_TYPE_ASSISTING = 3 BattleConst.SKILL_TYPE_PASSIVE = 4 BattleConst.SKILL_SELECT_COUNT = 3 BattleConst.DEFAULT_FACTOR = 10000 +BattleConst.TIME_FACTOR = 1000 BattleConst.INIT_POS_X = 140 -- 战斗单位初始化的坐标 BattleConst.UNIT_FRONT_POS_X = 0 -- 战斗单位身前的坐标 BattleConst.UNIT_BODY_WIDTH = 200 diff --git a/lua/app/module/battle/component/battle_unit_comp.lua b/lua/app/module/battle/component/battle_unit_comp.lua index 46e5da17..810ecec7 100644 --- a/lua/app/module/battle/component/battle_unit_comp.lua +++ b/lua/app/module/battle/component/battle_unit_comp.lua @@ -12,6 +12,7 @@ local DEFAULT_FACTOR = BattleConst.DEFAULT_FACTOR local PASSIVE_EVENT = BattleConst.PASSIVE_EVENT local HURT_STATE_CRIT = BattleConst.HURT_STATE_CRIT local EFFECT_TYPE = BattleConst.EFFECT_TYPE +local TIME_FACTOR = BattleConst.TIME_FACTOR function BattleUnitComp:ctor() end @@ -618,6 +619,7 @@ function BattleUnitComp:enterAssistingAttackState() self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self:playAnimation(attackName, false, false) + self:playSkillFx(skill) self:initPosition() end @@ -680,6 +682,7 @@ function BattleUnitComp:enterSkillAttackState() self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self:playAnimation(attackName, false, false) + self:playSkillFx(skill) end end @@ -833,6 +836,7 @@ function BattleUnitComp:doNextSkillAttack() self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self:playAnimation(attackName, false, false) + self:playSkillFx(self.currActiveSkill) DataManager.BattleData:resetTimeSpeed() end @@ -843,6 +847,7 @@ function BattleUnitComp:doNextNormalAttack() self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self:playAnimation(attackName, false, false) + self:playSkillFx(skill) self:attackAndSpeedUp() end @@ -853,19 +858,26 @@ function BattleUnitComp:doNextAttack() local skill = self.unitEntity:getNormalSkill() attackName = skill:getRandomNormalAttackName() if attackName then + self.currAttackDuration = self:getAnimationDuration(attackName) + self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) + self:playAnimation(attackName, false, false) + self:playSkillFx(attackName) self:attackAndSpeedUp() + else + self:moveBackToInitPosition() end elseif self.currActiveSkill then attackName = self.currActiveSkill:getSkillAttackName() if attackName then + self.currAttackDuration = self:getAnimationDuration(attackName) + self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) + self:playAnimation(attackName, false, false) + self:playSkillFx(self.currActiveSkill) DataManager.BattleData:resetTimeSpeed() + else + self:moveBackToInitPosition() end - end - if attackName then - self.currAttackDuration = self:getAnimationDuration(attackName) - self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) - self:playAnimation(attackName, false, false) - else -- 归位 + else self:moveBackToInitPosition() end end @@ -893,6 +905,7 @@ function BattleUnitComp:enterNormalAttackState() self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self:playAnimation(attackName, false, false) + self:playSkillFx(skill) self:attackAndSpeedUp() end end @@ -1158,6 +1171,114 @@ function BattleUnitComp:onRoundEnd() self.unitEntity:onRoundEnd() end +function BattleUnitComp:playSkillFx(skill) + self:playSkillSelfFx(skill) + self:playSkillTargetFx(skill) +end + +function BattleUnitComp:playSkillSelfFx(skill) + local fxId = skill:getFxSelf() + if fxId == nil then + return + end + local delay = skill:getFxSelfDelay() + self:playFx(skill, fxId, delay) +end + +function BattleUnitComp:playSkillTargetFx(skill) + local fxId = skill:getFxTarget() + if fxId == nil then + return + end + local delay = skill:getFxTargetDelay() + local targetType = skill:getTargetType() + if targetType == 1 then -- 自己 + self:playFx(skill, fxId, delay) + else + local target = self.battleController:getOtherSideMainUnit(self.side) + target:playFx(skill, fxId, delay) + end +end + +function BattleUnitComp:playFx(skill, fxId, delay) + if delay and delay > 0 then + if self.waitPlayFxList == nil then + self.waitPlayFxList = {} + self.waitPlayFxCount = 0 + end + self.waitPlayFxCount = self.waitPlayFxCount + 1 + local waitPlayFxObj = self.waitPlayFxList[self.waitPlayFxCount] + if waitPlayFxObj == nil then + waitPlayFxObj = {} + self.waitPlayFxList[self.waitPlayFxCount] = waitPlayFxObj + end + waitPlayFxObj.time = delay / TIME_FACTOR + waitPlayFxObj.fxId = fxId + waitPlayFxObj.skill = skill + waitPlayFxObj.sender = self + return + end + local fxInfo = BattleHelper:getFxConfig()[fxId] + if fxInfo then + self:getEffectAndPlay(skill, fxInfo) + end +end + +function BattleUnitComp:getEffectAndPlay(skill, fxInfo) + local bindNode = fxInfo.bind + local inScene = fxInfo.in_scene == 1 + local fxScale = fxInfo.scale or 1 + BattleHelper:getEffectAsync(fxInfo.res, self.battleController:getFxNode(), function(effectObj) + if inScene then + if bindNode then + local boneX, boneY, boneZ = self.baseObject:fastGetBonePosition(bindNode) + effectObj:setLocalPosition(boneX, boneY, boneZ) + else + effectObj:setLocalPosition(0, 0, 0) + end + else + if bindNode then + local boneFollower = BattleHelper:addSpineBoneFollowerGraphic(effectObj) + boneFollower.SkeletonGraphic = self.baseObject:getSkeletonGraphic() + boneFollower:SetBone(bindNode) + else + effectObj:setLocalPosition(0, 0, 0) + end + end + if fxInfo.follow_direction then + if self.side == BattleConst.SIDE_ATK then + if effectObj:getIsEulerAnglesFlip() then + effectObj:setLocalEulerAngles(0, 0, 0) + end + effectObj:setLocalScale(fxScale, fxScale, fxScale) + else + if effectObj:getIsEulerAnglesFlip() then + effectObj:setLocalEulerAngles(0, 180, 0) + effectObj:setLocalScale(fxScale, fxScale, fxScale) + else + effectObj:setLocalScale(-fxScale, fxScale, fxScale) + end + end + else + if effectObj:getIsEulerAnglesFlip() then + effectObj:setLocalEulerAngles(0, 0, 0) + end + effectObj:setLocalScale(fxScale, fxScale, fxScale) + end + -- if fxInfo.is_floor then + -- effectObj:setSortingOrder(0, 0) + -- else + -- effectObj:changeSortingOrderToFudge(BattleConst.BATTLE_BASE_ORDER, BattleConst.FX_SORTING_FUDGE_COEFFICIENT) + -- end + effectObj:play() + duration = duration or effectObj:getDuration() + local sid + sid = BattleHelper:performDurationDelay(duration, function() + BattleHelper:recycleEffect(effectObj) + end) + end) +end + function BattleUnitComp:tick(dt) if self.isClear then return @@ -1189,6 +1310,28 @@ function BattleUnitComp:tick(dt) end end +function BattleUnitComp:checkFx(dt) + if self.waitPlayFxCount == nil then + return + end + if self.waitPlayFxCount <= 0 then + return + end + for i = self.waitPlayFxCount, 1, -1 do + local fxObj = self.waitPlayFxList[i] + fxObj.time = fxObj.time - dt + if fxObj.time <= 0 then -- 该播了 + self:playFx(fxObj.skill, fxObj.fxId, 0) + local tailFxObj = self.waitPlayFxList[self.waitPlayFxCount] + fxObj.time = tailFxObj.time + fxObj.fxId = tailFxObj.fxId + fxObj.skill = tailFxObj.skill + fxObj.sender = tailFxObj.sender + self.waitPlayFxCount = self.waitPlayFxCount - 1 + end + end +end + function BattleUnitComp:checkPassiveEvent(eventId, targetComp, ...) if self.passiveSkills == nil then return @@ -1244,6 +1387,12 @@ function BattleUnitComp:clear() return end self.isClear = true + if self.waitPlayFxList then + for i = 1, #self.waitPlayFxList do + table.remove(self.waitPlayFxList) + end + self.waitPlayFxCount = 0 + end end function BattleUnitComp:recycle() diff --git a/lua/app/module/battle/controller/battle_controller.lua b/lua/app/module/battle/controller/battle_controller.lua index 98dd1e50..ad302024 100644 --- a/lua/app/module/battle/controller/battle_controller.lua +++ b/lua/app/module/battle/controller/battle_controller.lua @@ -2,6 +2,7 @@ local BattleHelper = require "app/module/battle/helper/battle_helper" local BattleScheduler = require "app/module/battle/helper/battle_scheduler" local BattleTeam = require "app/module/battle/team/battle_team" local BattlePassive = require "app/module/battle/helper/battle_passive" +local BattlePool = require "app/module/battle/helper/battle_pool" local BattleController = class("BattleController") @@ -178,6 +179,7 @@ function BattleController:init(params) BattleScheduler:init() BattleHelper:init() BattlePassive:init() + BattlePool:init() self:setTimeScale(DataManager.BattleData:getTimeScale()) self:bindData() self:initBattleTeam() @@ -1634,6 +1636,7 @@ function BattleController:clear() BattleScheduler:clear() BattleHelper:clear() BattlePassive:clear() + BattlePool:clear() self:unBindAll() DataManager.BattleData:resetTimeSpeed() end @@ -1648,6 +1651,10 @@ function BattleController:showEffectNumber(colorType, effectType, num, x, y) table.insert(self.effectTexts, effectTextComp) end +function BattleController:getFxNode() + return self.battleUI:getFxNode() +end + local function _addCurRoundAttr(self, instruction, callback) if instruction.effectList then local defComp = self:getOtherSideMainUnit(BattleConst.SIDE_ATK) diff --git a/lua/app/module/battle/helper/battle_helper.lua b/lua/app/module/battle/helper/battle_helper.lua index 9716ea56..45d29792 100644 --- a/lua/app/module/battle/helper/battle_helper.lua +++ b/lua/app/module/battle/helper/battle_helper.lua @@ -1,7 +1,10 @@ local UIPrefabObject = require "app/bf/unity/uiprefab_object" +local BattlePool = require "app/module/battle/helper/battle_pool" local BattleHelper = {} +local BATTLE_FX_PATH = "assets/prefabs/effects/battle/%s.prefab" + function BattleHelper:init() self.isClear = false self.characterPools = {} @@ -9,9 +12,19 @@ function BattleHelper:init() self.buffEffectPool = {} self.battleEffectTextMap = {} self.battleEffectTextPool = {} + self.battleFxPaths = {} + self.effectPools = BattlePool:getEffectPool() + self.effectMap = {} self.seed = tonumber(tostring(os.time()):reverse():sub(1,6)) end +function BattleHelper:getFxConfig() + if self.fxCfg == nil then + self.fxCfg = ConfigManager:getConfig("fx") + end + return self.fxCfg +end + function BattleHelper:setTimeScale(timeScale) if self.effectMap then for k, effect in pairs(self.effectMap) do @@ -79,6 +92,68 @@ function BattleHelper:recycleBattleHeroModel(modelId, character) end end +function BattleHelper:getEffectAsync(name, parent, callback) + local path = self.battleFxPaths[name] + if path == nil then + path = string.format(BATTLE_FX_PATH, name) + self.battleFxPaths[name] = path + end + local effect = self.effectPools:pop(path) + if effect then + if parent then + effect:setParent(parent, false) + end + if self.effectMap then + self.effectMap[effect:getInstanceID()] = effect + end + local timeScale = DataManager.BattleData:getTimeScale() + effect:setTimeScale(timeScale) + callback(effect) + else + EffectManager:loadBattleEffectAsync(path, parent, function(effect) + if self.effectMap then + effect:initParticleSystemRendererList() + self.effectMap[effect:getInstanceID()] = effect + local timeScale = DataManager.BattleData:getTimeScale() + effect:setTimeScale(timeScale) + callback(effect) + end + end) + end +end + +function BattleHelper:recycleEffect(effect) + if effect:isDestroyed() then + return + end + local comps = effect:getAllComponents() + if comps then + local boneFollower = comps[GConst.TYPEOF_UNITY_CLASS.BONE_FOLLOWER_GRAPHIC] + if boneFollower and boneFollower.SkeletonGraphic then + boneFollower.SkeletonGraphic = nil + end + end + effect:stop() + if self.effectPools then + self.effectPools:push(effect) + end + if self.effectMap then + self.effectMap[effect:getInstanceID()] = nil + end +end + +function BattleHelper:addSpineBoneFollowerGraphic(effectObj) + local boneFollower = effectObj:getComponent(GConst.TYPEOF_UNITY_CLASS.BONE_FOLLOWER_GRAPHIC) + if boneFollower == nil then + boneFollower = effectObj:addComponent(GConst.TYPEOF_UNITY_CLASS.BONE_FOLLOWER_GRAPHIC) + boneFollower.followBoneRotation = false + boneFollower.followSkeletonFlip = false + else + boneFollower.enabled = true + end + return boneFollower +end + function BattleHelper:setEffectTextCache(cache1, cache2, cache3, cache4) if self.effectTextCacheList == nil then self.effectTextCacheList = {} @@ -151,6 +226,9 @@ function BattleHelper:clear() self.buffEffectPool = nil self.battleEffectTextMap = nil self.battleEffectTextPool = nil + self.battleFxPaths = nil + self.effectPools = nil + self.effectMap = nil end return BattleHelper \ No newline at end of file diff --git a/lua/app/module/battle/helper/battle_pool.lua b/lua/app/module/battle/helper/battle_pool.lua new file mode 100644 index 00000000..f27c3a30 --- /dev/null +++ b/lua/app/module/battle/helper/battle_pool.lua @@ -0,0 +1,101 @@ +local BattlePool = {} + +function BattlePool:init() + self.effectPool = self:createEffectPool() +end + +function BattlePool:getEffectPool() + return self.effectPool +end + +function BattlePool:createObjPool() + local pool = { + dataPool = {}, + num = 0 + } + + function pool:pop() + local obj = nil + if pool.num > 0 then + obj = pool.dataPool[pool.num] + pool.dataPool[pool.num] = nil + pool.num = pool.num - 1 + end + return obj + end + + function pool:push(obj) + pool.num = pool.num + 1 + pool.dataPool[pool.num] = obj + end + return pool +end + +function BattlePool:createEffectPool() + local poolObj = BaseObject:create() + poolObj:initWithGameObject(CS.UnityEngine.GameObject()) + poolObj:dontDestroyOnLoad() + poolObj:setActive(false) + local pool = { + dataPool = {}, + poolObj = poolObj, + poolCount = 0 + } + + function pool:pop(path) + local obj = nil + local p = pool.dataPool[path] + if p and #p > 0 then + obj = table.remove(p) + if #p == 0 then + pool.poolCount = pool.poolCount - 1 + end + end + return obj + end + + function pool:push(obj, notSetParent) + local path = obj:getAssetPath() + local p = pool.dataPool[path] + if p == nil then + p = {} + pool.dataPool[path] = p + end + if #p == 0 then + pool.poolCount = pool.poolCount + 1 + end + table.insert(p, obj) + if not notSetParent then + obj:setParent(pool.poolObj, false) + end + end + + function pool:getPoolCount() + return pool.poolCount + end + + function pool:getRoot() + return pool.poolObj + end + + function pool:clearPool(path) + local p = pool.dataPool[path] + if p then + local count = #p + for i = 1, count do + local obj = table.remove(p) + obj:destroy() + end + pool.poolCount = pool.poolCount - 1 + end + end + + return pool +end + +function BattlePool:clear() + self.effectPool.poolObj:destroy() + self.effectPool = nil +end + +return BattlePool \ No newline at end of file diff --git a/lua/app/module/battle/helper/battle_pool.lua.meta b/lua/app/module/battle/helper/battle_pool.lua.meta new file mode 100644 index 00000000..331ac9b8 --- /dev/null +++ b/lua/app/module/battle/helper/battle_pool.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c0efc5a492f1d3c4cab5fd0202c2449f +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/ui/battle/battle_ui.lua b/lua/app/ui/battle/battle_ui.lua index 8562ac34..c1210059 100644 --- a/lua/app/ui/battle/battle_ui.lua +++ b/lua/app/ui/battle/battle_ui.lua @@ -42,6 +42,7 @@ function BattleUI:_display() self:initBattlefield() self:initNumberNode() self:initHpNode() + self:initFxNode() self:hideGenerateSkillGridCells() end @@ -359,6 +360,14 @@ function BattleUI:getBattleNumberYellow() return self.battleNumberYellow end +function BattleUI:initFxNode() + self.fxNode = self.uiMap["battle_ui.batttle_fx_node"] +end + +function BattleUI:getFxNode() + return self.fxNode +end + function BattleUI:initHpNode() self.hpProgressLeft = self.uiMap["battle_ui.top_node.bg_l.atk_slider_green"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) self.hpProgressRight = self.uiMap["battle_ui.top_node.bg_r.def_slider_red"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) diff --git a/lua/app/userdata/battle/skill/battle_skill_entity.lua b/lua/app/userdata/battle/skill/battle_skill_entity.lua index 99e1547a..38d464e5 100644 --- a/lua/app/userdata/battle/skill/battle_skill_entity.lua +++ b/lua/app/userdata/battle/skill/battle_skill_entity.lua @@ -168,6 +168,22 @@ function BattleSkillEntity:getPassiveTriggerId() return self.skillInfo.trigger end +function BattleSkillEntity:getFxSelf() + return self.skillInfo.fx_self +end + +function BattleSkillEntity:getFxSelfDelay() + return self.skillInfo.fx_self_delay +end + +function BattleSkillEntity:getFxTarget() + return self.skillInfo.fx_target +end + +function BattleSkillEntity:getFxTargetDelay() + return self.skillInfo.fx_target_delay +end + function BattleSkillEntity:getRecordData(name) if self.recordData == nil then self.recordData = {}