技能特效

This commit is contained in:
chenxi 2023-04-21 15:52:50 +08:00
parent 3ed97017f3
commit 4d4bd0fc61
10 changed files with 378 additions and 7 deletions

View File

@ -254,7 +254,6 @@ end
function CharacterSpineObject:onDestroy() function CharacterSpineObject:onDestroy()
self:removeAnimationCompleteCallback() self:removeAnimationCompleteCallback()
BaseObject.onDestroy(self) BaseObject.onDestroy(self)
self.skeletonAnimation = nil
self.animationState = nil self.animationState = nil
end end

View File

@ -110,6 +110,7 @@ GConst.TYPEOF_UNITY_CLASS = {
SKELETON_ANIMATION = typeof(CS.Spine.Unity.SkeletonAnimation), SKELETON_ANIMATION = typeof(CS.Spine.Unity.SkeletonAnimation),
SKELETON_DATA_ASSET = typeof(CS.Spine.Unity.SkeletonDataAsset), SKELETON_DATA_ASSET = typeof(CS.Spine.Unity.SkeletonDataAsset),
BONE_FOLLOWER = typeof(CS.Spine.Unity.BoneFollower), BONE_FOLLOWER = typeof(CS.Spine.Unity.BoneFollower),
BONE_FOLLOWER_GRAPHIC = typeof(CS.Spine.Unity.BoneFollowerGraphic),
-- 自定义组件 -- 自定义组件
MONKEY_POST = typeof(CS.MonkeyPost), MONKEY_POST = typeof(CS.MonkeyPost),
CLOUD_CONTROL = typeof(CS.CloudControl), CLOUD_CONTROL = typeof(CS.CloudControl),

View File

@ -18,6 +18,7 @@ BattleConst.SKILL_TYPE_ASSISTING = 3
BattleConst.SKILL_TYPE_PASSIVE = 4 BattleConst.SKILL_TYPE_PASSIVE = 4
BattleConst.SKILL_SELECT_COUNT = 3 BattleConst.SKILL_SELECT_COUNT = 3
BattleConst.DEFAULT_FACTOR = 10000 BattleConst.DEFAULT_FACTOR = 10000
BattleConst.TIME_FACTOR = 1000
BattleConst.INIT_POS_X = 140 -- 战斗单位初始化的坐标 BattleConst.INIT_POS_X = 140 -- 战斗单位初始化的坐标
BattleConst.UNIT_FRONT_POS_X = 0 -- 战斗单位身前的坐标 BattleConst.UNIT_FRONT_POS_X = 0 -- 战斗单位身前的坐标
BattleConst.UNIT_BODY_WIDTH = 200 BattleConst.UNIT_BODY_WIDTH = 200

View File

@ -12,6 +12,7 @@ local DEFAULT_FACTOR = BattleConst.DEFAULT_FACTOR
local PASSIVE_EVENT = BattleConst.PASSIVE_EVENT local PASSIVE_EVENT = BattleConst.PASSIVE_EVENT
local HURT_STATE_CRIT = BattleConst.HURT_STATE_CRIT local HURT_STATE_CRIT = BattleConst.HURT_STATE_CRIT
local EFFECT_TYPE = BattleConst.EFFECT_TYPE local EFFECT_TYPE = BattleConst.EFFECT_TYPE
local TIME_FACTOR = BattleConst.TIME_FACTOR
function BattleUnitComp:ctor() function BattleUnitComp:ctor()
end end
@ -618,6 +619,7 @@ function BattleUnitComp:enterAssistingAttackState()
self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false) self:playAnimation(attackName, false, false)
self:playSkillFx(skill)
self:initPosition() self:initPosition()
end end
@ -680,6 +682,7 @@ function BattleUnitComp:enterSkillAttackState()
self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false) self:playAnimation(attackName, false, false)
self:playSkillFx(skill)
end end
end end
@ -833,6 +836,7 @@ function BattleUnitComp:doNextSkillAttack()
self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false) self:playAnimation(attackName, false, false)
self:playSkillFx(self.currActiveSkill)
DataManager.BattleData:resetTimeSpeed() DataManager.BattleData:resetTimeSpeed()
end end
@ -843,6 +847,7 @@ function BattleUnitComp:doNextNormalAttack()
self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false) self:playAnimation(attackName, false, false)
self:playSkillFx(skill)
self:attackAndSpeedUp() self:attackAndSpeedUp()
end end
@ -853,19 +858,26 @@ function BattleUnitComp:doNextAttack()
local skill = self.unitEntity:getNormalSkill() local skill = self.unitEntity:getNormalSkill()
attackName = skill:getRandomNormalAttackName() attackName = skill:getRandomNormalAttackName()
if attackName then if attackName then
self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false)
self:playSkillFx(attackName)
self:attackAndSpeedUp() self:attackAndSpeedUp()
else
self:moveBackToInitPosition()
end end
elseif self.currActiveSkill then elseif self.currActiveSkill then
attackName = self.currActiveSkill:getSkillAttackName() attackName = self.currActiveSkill:getSkillAttackName()
if attackName then
DataManager.BattleData:resetTimeSpeed()
end
end
if attackName then if attackName then
self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false) self:playAnimation(attackName, false, false)
else -- 归位 self:playSkillFx(self.currActiveSkill)
DataManager.BattleData:resetTimeSpeed()
else
self:moveBackToInitPosition()
end
else
self:moveBackToInitPosition() self:moveBackToInitPosition()
end end
end end
@ -893,6 +905,7 @@ function BattleUnitComp:enterNormalAttackState()
self.currAttackDuration = self:getAnimationDuration(attackName) self.currAttackDuration = self:getAnimationDuration(attackName)
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName) self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
self:playAnimation(attackName, false, false) self:playAnimation(attackName, false, false)
self:playSkillFx(skill)
self:attackAndSpeedUp() self:attackAndSpeedUp()
end end
end end
@ -1158,6 +1171,114 @@ function BattleUnitComp:onRoundEnd()
self.unitEntity:onRoundEnd() self.unitEntity:onRoundEnd()
end 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) function BattleUnitComp:tick(dt)
if self.isClear then if self.isClear then
return return
@ -1189,6 +1310,28 @@ function BattleUnitComp:tick(dt)
end end
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, ...) function BattleUnitComp:checkPassiveEvent(eventId, targetComp, ...)
if self.passiveSkills == nil then if self.passiveSkills == nil then
return return
@ -1244,6 +1387,12 @@ function BattleUnitComp:clear()
return return
end end
self.isClear = true self.isClear = true
if self.waitPlayFxList then
for i = 1, #self.waitPlayFxList do
table.remove(self.waitPlayFxList)
end
self.waitPlayFxCount = 0
end
end end
function BattleUnitComp:recycle() function BattleUnitComp:recycle()

View File

@ -2,6 +2,7 @@ local BattleHelper = require "app/module/battle/helper/battle_helper"
local BattleScheduler = require "app/module/battle/helper/battle_scheduler" local BattleScheduler = require "app/module/battle/helper/battle_scheduler"
local BattleTeam = require "app/module/battle/team/battle_team" local BattleTeam = require "app/module/battle/team/battle_team"
local BattlePassive = require "app/module/battle/helper/battle_passive" local BattlePassive = require "app/module/battle/helper/battle_passive"
local BattlePool = require "app/module/battle/helper/battle_pool"
local BattleController = class("BattleController") local BattleController = class("BattleController")
@ -178,6 +179,7 @@ function BattleController:init(params)
BattleScheduler:init() BattleScheduler:init()
BattleHelper:init() BattleHelper:init()
BattlePassive:init() BattlePassive:init()
BattlePool:init()
self:setTimeScale(DataManager.BattleData:getTimeScale()) self:setTimeScale(DataManager.BattleData:getTimeScale())
self:bindData() self:bindData()
self:initBattleTeam() self:initBattleTeam()
@ -1634,6 +1636,7 @@ function BattleController:clear()
BattleScheduler:clear() BattleScheduler:clear()
BattleHelper:clear() BattleHelper:clear()
BattlePassive:clear() BattlePassive:clear()
BattlePool:clear()
self:unBindAll() self:unBindAll()
DataManager.BattleData:resetTimeSpeed() DataManager.BattleData:resetTimeSpeed()
end end
@ -1648,6 +1651,10 @@ function BattleController:showEffectNumber(colorType, effectType, num, x, y)
table.insert(self.effectTexts, effectTextComp) table.insert(self.effectTexts, effectTextComp)
end end
function BattleController:getFxNode()
return self.battleUI:getFxNode()
end
local function _addCurRoundAttr(self, instruction, callback) local function _addCurRoundAttr(self, instruction, callback)
if instruction.effectList then if instruction.effectList then
local defComp = self:getOtherSideMainUnit(BattleConst.SIDE_ATK) local defComp = self:getOtherSideMainUnit(BattleConst.SIDE_ATK)

View File

@ -1,7 +1,10 @@
local UIPrefabObject = require "app/bf/unity/uiprefab_object" local UIPrefabObject = require "app/bf/unity/uiprefab_object"
local BattlePool = require "app/module/battle/helper/battle_pool"
local BattleHelper = {} local BattleHelper = {}
local BATTLE_FX_PATH = "assets/prefabs/effects/battle/%s.prefab"
function BattleHelper:init() function BattleHelper:init()
self.isClear = false self.isClear = false
self.characterPools = {} self.characterPools = {}
@ -9,9 +12,19 @@ function BattleHelper:init()
self.buffEffectPool = {} self.buffEffectPool = {}
self.battleEffectTextMap = {} self.battleEffectTextMap = {}
self.battleEffectTextPool = {} self.battleEffectTextPool = {}
self.battleFxPaths = {}
self.effectPools = BattlePool:getEffectPool()
self.effectMap = {}
self.seed = tonumber(tostring(os.time()):reverse():sub(1,6)) self.seed = tonumber(tostring(os.time()):reverse():sub(1,6))
end end
function BattleHelper:getFxConfig()
if self.fxCfg == nil then
self.fxCfg = ConfigManager:getConfig("fx")
end
return self.fxCfg
end
function BattleHelper:setTimeScale(timeScale) function BattleHelper:setTimeScale(timeScale)
if self.effectMap then if self.effectMap then
for k, effect in pairs(self.effectMap) do for k, effect in pairs(self.effectMap) do
@ -79,6 +92,68 @@ function BattleHelper:recycleBattleHeroModel(modelId, character)
end end
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) function BattleHelper:setEffectTextCache(cache1, cache2, cache3, cache4)
if self.effectTextCacheList == nil then if self.effectTextCacheList == nil then
self.effectTextCacheList = {} self.effectTextCacheList = {}
@ -151,6 +226,9 @@ function BattleHelper:clear()
self.buffEffectPool = nil self.buffEffectPool = nil
self.battleEffectTextMap = nil self.battleEffectTextMap = nil
self.battleEffectTextPool = nil self.battleEffectTextPool = nil
self.battleFxPaths = nil
self.effectPools = nil
self.effectMap = nil
end end
return BattleHelper return BattleHelper

View File

@ -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

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c0efc5a492f1d3c4cab5fd0202c2449f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

View File

@ -42,6 +42,7 @@ function BattleUI:_display()
self:initBattlefield() self:initBattlefield()
self:initNumberNode() self:initNumberNode()
self:initHpNode() self:initHpNode()
self:initFxNode()
self:hideGenerateSkillGridCells() self:hideGenerateSkillGridCells()
end end
@ -359,6 +360,14 @@ function BattleUI:getBattleNumberYellow()
return self.battleNumberYellow return self.battleNumberYellow
end end
function BattleUI:initFxNode()
self.fxNode = self.uiMap["battle_ui.batttle_fx_node"]
end
function BattleUI:getFxNode()
return self.fxNode
end
function BattleUI:initHpNode() function BattleUI:initHpNode()
self.hpProgressLeft = self.uiMap["battle_ui.top_node.bg_l.atk_slider_green"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) 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) self.hpProgressRight = self.uiMap["battle_ui.top_node.bg_r.def_slider_red"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER)

View File

@ -168,6 +168,22 @@ function BattleSkillEntity:getPassiveTriggerId()
return self.skillInfo.trigger return self.skillInfo.trigger
end 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) function BattleSkillEntity:getRecordData(name)
if self.recordData == nil then if self.recordData == nil then
self.recordData = {} self.recordData = {}