PGRData/Script/matrix/xui/xuicharacter/XUiPanelRoleModel.lua
2024-09-01 22:49:41 +02:00

2411 lines
84 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---@class XUiPanelRoleModel
local XUiPanelRoleModel = XClass(nil, "XUiPanelRoleModel")
local AnimeLayer = {
Body = 0,
Face = 1
}
--==============================--
--- RoleModelPool = {["model"] = model, ["weaponList"] = list, ["characterId"] = characterId}
--==============================--
function XUiPanelRoleModel:Ctor(
ui,
refName,
hideWeapon,
showShadow,
loadClip,
setFocus,
fixLight,
playEffectFunc,
clearUiChildren,
useMultiModel)
self.Ui = ui
self.RefName = refName or "DefaultName"
self.GameObject = ui.gameObject
self.Transform = ui.transform
if clearUiChildren then -- 初始化时是否清空model挂点下所有物体
XTool.DestroyChildren(ui.gameObject)
end
self.RoleModelPool = {}
self.HideWeapon = hideWeapon and true or false
self.ShowShadow = showShadow
self.SetFocus = setFocus
self.FixLight = fixLight
self.PlayEffectFunc = playEffectFunc
if loadClip == nil then
self.InitLoadClip = true
else
self.InitLoadClip = loadClip and true
end
self.LoadClip = self.InitLoadClip
self.IsStandAnimaShowWeapon = false
self.StandAnimaShowWeaponList = {}
self.CueId = nil
self.UiStandCallBack = {}
self.NowFashionId = nil
-- 卡列演唱会皮肤临时处理定时器
self.TempProcessTimer = nil
if useMultiModel == nil then
self.UseMultiModel = true
end
end
--设置默认动画
function XUiPanelRoleModel:SetDefaultAnimation(animationName)
self.DefaultAnimation = animationName
end
--[[ 根据roleName从UiModel获取配置
如果没有Display控制器直接加载默认动画否则加载控制器并播控制器默认动画
PS:如果配置了Fasion控制层直接以Fasion控制器为主
]]
function XUiPanelRoleModel:UpdateRoleModelWithAutoConfig(
roleName,
targetUiName,
cb,
isReLoadController,
needFightController)
local displayController = XModelManager.GetUiDisplayControllerPath(roleName)
local defaultAnimation = XModelManager.GetUiDefaultAnimationPath(roleName)
self:UpdateRoleModel(
roleName,
nil,
targetUiName,
cb,
defaultAnimation ~= nil,
displayController ~= nil,
isReLoadController,
needFightController
)
end
function XUiPanelRoleModel:UpdateRoleModel(
roleName,
targetPanelRole,
targetUiName,
cb,
IsReLoadAnime,
needDisplayController,
IsReLoadController,
needFightController)
if not roleName then
XLog.Error("XUiPanelCharRole:UpdateRoleModel 函数错误: 参数roleName不能为空")
return
end
local isSpecialModel, isMultiModel = XModelManager.CheckModelIsSpecial(roleName, targetUiName)
if self.UseMultiModel and isMultiModel then
if not self.NewPanel then
self.UseMultiModel = false
self.NewPanel = XUiPanelRoleModel.New(
self.Ui,
self.RefName,
self.HideWeapon,
self.ShowShadow,nil,nil,nil,nil,nil,self.UseMultiModel)
end
end
if self.NewPanel and isMultiModel then
local minorModelId = XModelManager.GetMinorModelId(roleName, targetUiName)
if not minorModelId then
self.NewPanel = nil
else
self.NewPanel:UpdateRoleModel(
minorModelId,
targetPanelRole,
targetUiName,
cb,
IsReLoadAnime,
needDisplayController,
IsReLoadController,
needFightController)
end
end
--特殊模型 && 单模型
if isSpecialModel and not isMultiModel then
roleName = XModelManager.GetSpecialModelId(roleName, targetUiName)
end
local defaultAnimation = self.DefaultAnimation or XModelManager.GetUiDefaultAnimationPath(roleName)
self.DefaultAnimation = nil
local modelPool = self.RoleModelPool
local curRoleName = self.CurRoleName
local curModelInfo = modelPool[curRoleName]
if curModelInfo then
if XTool.UObjIsNil(curModelInfo.Model.gameObject) then
XLog.Error("[UpdateRoleModel] NullReferenceException: Object reference not set to an instance of an object")
modelPool[curRoleName] = nil
return
end
curModelInfo.Model.gameObject:SetActiveEx(false)
curModelInfo.time = XTime.GetServerNowTimestamp()
end
if curRoleName ~= roleName then
self.CurRoleName = roleName
end
local runtimeControllerName
--特殊时装只加载配置的动画状态机Controller
runtimeControllerName = (not needFightController) and XModelManager.GetUiFashionControllerPath(roleName)
if not runtimeControllerName then
--如果没有配置再加载配置展示用的动画状态机Controller
if needDisplayController then
runtimeControllerName = XModelManager.GetUiDisplayControllerPath(roleName)
end
if needFightController then
runtimeControllerName = XModelManager.GetUiControllerPath(roleName)
end
end
--如果用状态机就不需要手动加载animclip了
if runtimeControllerName then
self.LoadClip = nil
else
self.LoadClip = self.InitLoadClip --复原成一开始传入的参数
end
local needRemove = nil
local nowTime = XTime.GetServerNowTimestamp()
for k, v in pairs(modelPool) do
--不等于当前要显示的模型且时间超出5秒的都要删掉
if k ~= roleName and v and v.time then
local diff = nowTime - v.time
if diff >= 5 then
if needRemove == nil then
needRemove = {}
end
table.insert(needRemove, k)
end
end
end
--删除超时的模型
if needRemove then
for i = 1, #needRemove do
local tempRoleName = needRemove[i]
local modelInfo = modelPool[tempRoleName]
if modelInfo.Model and modelInfo.Model:Exist() then
CS.UnityEngine.Object.Destroy(modelInfo.Model.gameObject)
end
modelPool[tempRoleName] = nil
--如果是多重模型,删除时一并删除副模型
local isSpModel, isMulModel = XModelManager.CheckModelIsSpecial(tempRoleName, targetUiName)
if isSpModel and isMulModel and self.NewPanel then
local tempMinorModelId = XModelManager.GetMinorModelId(tempRoleName, targetUiName)
if tempMinorModelId then
self.NewPanel.RoleModelPool[tempMinorModelId] = nil
end
end
end
end
local modelInfo = modelPool[roleName]
local cueId = self.CueId
--UiStand播放背景音乐
local uiStandVoiceCb = function(model)
if cueId then
if CS.XAudioManager.IsOpenFashionVoice == 1 then
self:SetUiStandAnimaFinishCallback(model, function()
XSoundManager.Stop(cueId)
XSoundManager.PlaySoundByType(cueId, XSoundManager.SoundType.Sound)
end, function()
XSoundManager.Stop(cueId)
end,false, true)
end
end
if cb then
cb(model)
end
end
if IsReLoadAnime then
self:LoadModelAndReLoadAnime(
modelInfo,
targetUiName,
roleName,
defaultAnimation,
--[[cb]]uiStandVoiceCb,
runtimeControllerName,
IsReLoadController
)
else
self:LoadModelAndNotReLoadAnime(
modelInfo,
targetUiName,
roleName,
defaultAnimation,
--[[cb]]uiStandVoiceCb,
runtimeControllerName,
IsReLoadController
)
end
end
function XUiPanelRoleModel:LoadModelAndNotReLoadAnime(
modelInfo,
targetUiName,
roleName,
defaultAnimation,
cb,
runtimeControllerName,
IsReLoadController) --更新加载同一个模型时不重新加载动画
if modelInfo then
modelInfo.Model.gameObject:SetActiveEx(true)
if IsReLoadController then
self:RoleModelLoaded(roleName, targetUiName, cb, runtimeControllerName)
else
self:RoleModelLoaded(roleName, targetUiName, cb)
end
else
XModelManager.LoadRoleModel(
self.CurRoleName,
self.Transform,
function(model)
local tmpModelInfo = {}
tmpModelInfo.Model = model
tmpModelInfo.RenderingProxy = CS.XNPCRendingUIProxy.GetNPCRendingUIProxy(model)
self.RoleModelPool[roleName] = tmpModelInfo
if self.LoadClip then
self:LoadAnimationClips(
model.gameObject,
defaultAnimation,
function()
self:RoleModelLoaded(roleName, targetUiName, cb, runtimeControllerName)
end
)
else
self:RoleModelLoaded(roleName, targetUiName, cb, runtimeControllerName)
end
local isSpecialModel, isMultiModel = XModelManager.CheckModelIsSpecial(self.CurRoleName, targetUiName)
if self.NewPanel and isMultiModel then
local newModelName = XModelManager.GetMinorModelId(self.CurRoleName, targetUiName)
local info = self.NewPanel.RoleModelPool[newModelName]
if info then
info.Model.transform:SetParent(model.transform, false)
info.Model.gameObject:SetLayerRecursively(model.gameObject.layer)
end
end
end)
end
end
function XUiPanelRoleModel:LoadModelAndReLoadAnime(
modelInfo,
targetUiName,
roleName,
defaultAnimation,
cb,
runtimeControllerName,
IsReLoadController) --更新加载同一个模型时重新加载动画
if modelInfo then
modelInfo.Model.gameObject:SetActiveEx(true)
self:LoadSingleAnimationClip(
modelInfo.Model.gameObject,
defaultAnimation,
function()
self:RoleModelLoaded(roleName, targetUiName, cb)
end
)
else
XModelManager.LoadRoleModel(
self.CurRoleName,
self.Transform,
function(model)
local tmpModelInfo = {}
tmpModelInfo.Model = model
tmpModelInfo.RenderingProxy = CS.XNPCRendingUIProxy.GetNPCRendingUIProxy(model)
self.RoleModelPool[roleName] = tmpModelInfo
self:LoadSingleAnimationClip(
model.gameObject,
defaultAnimation,
function()
self:RoleModelLoaded(roleName, targetUiName, cb)
end
)
local isSpecialModel, isMultiModel = XModelManager.CheckModelIsSpecial(self.CurRoleName, targetUiName)
if self.NewPanel and isMultiModel then
local newModelName = XModelManager.GetMinorModelId(self.CurRoleName, targetUiName)
local info = self.NewPanel.RoleModelPool[newModelName]
if info then
info.Model.transform:SetParent(model.transform, false)
info.Model.gameObject:SetLayerRecursively(model.gameObject.layer)
end
end
end)
end
end
function XUiPanelRoleModel:LoadAnimationClips(model, defaultAnimation, cb)
if model == nil or not model:Exist() then
XLog.Error("XUiPanelRoleModel.LoadAnimation 函数错误参数model不能为空")
return
end
local loadAnimationClip = model.gameObject:GetComponent(typeof(CS.XLoadAnimationClip))
if loadAnimationClip == nil or not loadAnimationClip:Exist() then
loadAnimationClip = model.gameObject:AddComponent(typeof(CS.XLoadAnimationClip))
if not loadAnimationClip:Exist() then
XLog.Error("XUiPanelRoleModel.LoadAnimation XLoadAnimationClip不存在")
return
end
local clips = { defaultAnimation }
if XTool.IsTableEmpty(clips) then
XLog.Error("XUiPanelRoleModel.LoadAnimation error: defaultAnimation为空")
return
end
local activeState = model.gameObject.activeSelf
model.gameObject:SetActiveEx(false)
loadAnimationClip:LoadAnimationClips(
clips,
function()
model.gameObject:SetActiveEx(activeState)
if cb then
cb()
end
end
)
else
if cb then
cb()
end
end
end
function XUiPanelRoleModel:LoadSingleAnimationClip(model, defaultAnimation, cb)
if model == nil or not model:Exist() then
local modelPool = self.RoleModelPool
local curRoleName = self.CurRoleName
local curModelInfo = modelPool[curRoleName]
if curModelInfo then
model = curModelInfo.Model.gameObject
else
XLog.Error("XUiPanelRoleModel.LoadAnimation model = nil ")
return
end
end
local loadAnimationClip = model.gameObject:GetComponent(typeof(CS.XLoadAnimationClip))
if loadAnimationClip == nil or not loadAnimationClip:Exist() then
loadAnimationClip = model.gameObject:AddComponent(typeof(CS.XLoadAnimationClip))
end
local activeState = model.gameObject.activeSelf
model.gameObject:SetActiveEx(false)
loadAnimationClip:LoadSingleAnimationClip(
defaultAnimation,
function()
model.gameObject:SetActiveEx(activeState)
if cb then
cb()
end
end
)
end
function XUiPanelRoleModel:RoleModelLoaded(name, uiName, cb, runtimeControllerName)
if not self.CurRoleName then
return
end
local modelInfo = self.RoleModelPool[self.CurRoleName]
if not modelInfo then
return
end
local model = modelInfo.Model
XModelManager.SetRoleTransform(name, model, uiName)
XModelManager.SetRoleCamera(name, model.transform.parent.parent.parent, uiName)
if runtimeControllerName then
local animator = model:GetComponent("Animator")
local runtimeController = CS.LoadHelper.LoadUiController(runtimeControllerName, self.RefName)
animator.runtimeAnimatorController = runtimeController
end
if self.SetFocus then
CS.XGraphicManager.Focus = model.transform
end
if cb then
cb(model)
end
uiName = uiName or self.RefName
XModelManager.HandleUiModelNodeActive(uiName, name, model)
-- 阴影要放在武器模型加载完之后
if self.ShowShadow then
CS.XShadowHelper.AddShadow(self.GameObject, true)
end
-- 卡列尼娜·辉晓Uistand动作武器抖动临时处理
if self.TempProcessTimer then
XScheduleManager.UnSchedule(self.TempProcessTimer)
self.TempProcessTimer = nil
end
if not XTool.UObjIsNil(model) and model.name == "R4KalieninaMd019381(Clone)" then
local weaponModelRoot = model.transform:FindTransform("WeaponCase1")
if not XTool.UObjIsNil(weaponModelRoot) and weaponModelRoot.childCount ~= 0 then
local weaponModel = weaponModelRoot:GetChild(0)
if not XTool.UObjIsNil(weaponModel) then
self.TempProcessTimer = XScheduleManager.ScheduleOnce(function()
weaponModel:SetParent(model.transform, true)
end, 1)
end
end
end
-- 卡列尼娜·辉晓Uistand动作武器抖动临时处理 END
-- 只有不是三个模型同时出现的界面调用此接口
if not self.FixLight then
CS.XShadowHelper.SetCharRealtimeShadow(self.GameObject, true)
end
end
function XUiPanelRoleModel:GetModelName(characterId)
local quality
local character = XDataCenter.CharacterManager.GetCharacter(characterId)
if character then
quality = character.Quality
end
return XDataCenter.CharacterManager.GetCharModel(characterId, quality)
end
--region---------------------------------加载Ui角色动作特效start---------------------------
--==============================--
--desc: (外部接口)加载当前Ui角色动作特效
--@characterId: 角色id
--@actionId: 动作Id
--==============================--
function XUiPanelRoleModel:LoadCharacterUiEffect(characterId, actionId, isNotSelf, weaponFashionId, isShowDefaultWeapon)
if not characterId then
return
end
local fashionId = nil
if not self.NowFashionId then
fashionId = XDataCenter.CharacterManager.GetShowFashionId(characterId, isNotSelf)
else
fashionId = self.NowFashionId
end
local id, rootName, effectPath = XCharacterUiEffectConfig.GetEffectInfo(characterId, fashionId, actionId)
local model = self.RoleModelPool[self.CurRoleName]
if not model then return end
if not model.CharacterId then
model.CharacterId = characterId
end
self:SetCurrentUiEffectActive(model.UiEffect, false)
self:SetCurrentUiEffectActive(model.UiEquipEffect, false)
if not model.NotUiStand1 then
local playRoleAnimation = model.Model.gameObject:GetComponent("XPlayRoleAnimation")
if playRoleAnimation then
local defaultAnimeName = playRoleAnimation.DefaultClip
model.NotUiStand1 = defaultAnimeName ~= "UiStand1"
else
model.NotUiStand1 = true
return
end
end
if not actionId and model.NotUiStand1 then
return
end
if not actionId then
model.UiDefaultId = id
end
self:LoadCharacterUiEquipEffect(model, characterId, fashionId, actionId, isShowDefaultWeapon, weaponFashionId)
self:PlayCharacterUiEffect(model, id, rootName, effectPath)
end
--==============================--
--desc: (外部接口)加载时装展示Ui角色动作特效
--@characterId: 角色id
--@fashionId: 时装Id
--==============================--
function XUiPanelRoleModel:LoadResCharacterUiEffect(characterId, fashionId, weaponFashionId, isShowDefaultWeapon, equipTemplateId)
if not characterId then
return
end
local id, rootName, effectPath = XCharacterUiEffectConfig.GetEffectInfo(characterId, fashionId)
if not id or not effectPath then
return
end
local model = self.RoleModelPool[self.CurRoleName]
if not model.CharacterId then
model.CharacterId = characterId
end
self:SetCurrentUiEffectActive(model.UiEffect, false)
self:SetCurrentUiEffectActive(model.UiEquipEffect, false)
local playRoleAnimation = model.Model.gameObject:GetComponent("XPlayRoleAnimation")
if playRoleAnimation then
local defaultAnimeName = playRoleAnimation.DefaultClip
model.NotUiStand1 = defaultAnimeName ~= "UiStand1"
if model.NotUiStand1 then
return
end
else
model.NotUiStand1 = true
return
end
self:LoadCharacterUiEquipEffect(model, characterId, fashionId, nil, isShowDefaultWeapon, weaponFashionId, equipTemplateId)
self:PlayCharacterUiEffect(model, id, rootName, effectPath)
end
--==============================--
--desc: 加载当前Q版角色动作特效
--@characterId: 角色id
--==============================--
function XUiPanelRoleModel:LoadCharacterCuteUiEffect(characterId)
if not XTool.IsNumberValid(characterId) then
return
end
local model = self.RoleModelPool[self.CurRoleName]
if not model then
return
end
if not model.CharacterId then
model.CharacterId = characterId
end
if XTool.UObjIsNil(model.Model.gameObject) then
return
end
local playRoleAnimation = model.Model.gameObject:GetComponent("XPlayRoleAnimation")
if not playRoleAnimation then
return
end
-- Q版角色特殊处理 直接取默认动作id
local actionId = playRoleAnimation.DefaultClip
local id, rootName, effectPath = XCharacterCuteConfig.GetEffectInfo(characterId, actionId)
self:SetCurrentUiEffectActive(model.UiEffect, false)
self:PlayCharacterUiEffect(model, id, rootName, effectPath)
end
--==============================--
--desc: (外部接口)加载Ui角色默认动作特效
--==============================--
function XUiPanelRoleModel:LoadCurrentCharacterDefaultUiEffect()
local model = self.RoleModelPool[self.CurRoleName]
if model.NotUiStand1 or not model.UiDefaultId then
return
end
self:SetCurrentUiEffectActive(model.UiEffect, false)
self:SetCurrentUiEffectActive(model.UiEquipEffect, false)
local fashionId = XDataCenter.CharacterManager.GetShowFashionId(model.CharacterId)
local _, rootName, effectPath = XCharacterUiEffectConfig.GetEffectInfo(model.CharacterId, fashionId)
self:LoadCharacterUiEquipEffect(model, model.CharacterId, fashionId)
self:PlayCharacterUiEffect(model, model.UiDefaultId, rootName, effectPath)
end
--==============================--
--desc: 播放Ui角色动作特效
--==============================--
function XUiPanelRoleModel:PlayCharacterUiEffect(model, id, rootName, effectPath)
if not id or not effectPath then
return
end
self:GetModelUiEffect(model, id, rootName, effectPath)
self:SetCurrentUiEffectActive(model.UiEffect, true)
self:BindEffectByModel(model)
self:SetReActiveUiEffect(model)
end
function XUiPanelRoleModel:LoadCharacterUiEquipEffect(model, characterId, fashionId, actionId, isShowDefaultWeapon, weaponFashionId, equipTemplateId)
local equipModelIdList
if equipTemplateId then
local equip = { TemplateId = equipTemplateId }
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByEquipData(equip, weaponFashionId)
else
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByCharacterId(characterId, isShowDefaultWeapon, weaponFashionId)
end
local idList, rootName2EffectPath = {}, {}
for _, equipModelId in ipairs(equipModelIdList or {}) do
local effectId, name2EffectMap = XCharacterUiEffectConfig.GetEquipEffectInfo(equipModelId, fashionId, actionId)
if effectId then
table.insert(idList, effectId)
for rootName, effectList in pairs(name2EffectMap or {}) do
rootName2EffectPath[rootName] = effectList
end
end
end
if not XTool.IsTableEmpty(idList) then
self:GetModelUiEquipEffect(model, table.concat(idList, "-"), rootName2EffectPath)
end
end
function XUiPanelRoleModel:LoadCharacterUiEquipEffectOther(model, equip, fashionId, actionId, weaponFashionId)
local idList, rootName2EffectPath = {}, {}
local equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByEquipData(equip, weaponFashionId)
for _, equipModelId in ipairs(equipModelIdList or {}) do
local effectId, name2EffectMap = XCharacterUiEffectConfig.GetEquipEffectInfo(equipModelId, fashionId, actionId)
if effectId then
table.insert(idList, effectId)
for rootName, effectList in pairs(name2EffectMap or {}) do
rootName2EffectPath[rootName] = effectList
end
end
end
if not XTool.IsTableEmpty(idList) then
self:GetModelUiEquipEffect(model, table.concat(idList, "-"), rootName2EffectPath)
end
end
--==============================--
--desc: 获取Ui角色动作特效
--==============================--
function XUiPanelRoleModel:GetModelUiEffect(model, id, rootNameArray, effectPathArray)
if model.UiEffect and model.CurrentUiEffectId == id then
return model.UiEffect
end
model.CurrentUiEffectId = id
-- 不管上次的特效因为XUiLoadPrefab已经处理了重复加载问题XUiLoadPrefab组件同一个挂点只会生成一个Prefab旧的会自动销毁
model.UiEffect = self:ClearUiEffectList(model.UiEffect)
local uiEffectArray = model.UiEffect
for idx, rootName in pairs(rootNameArray) do
for _, effectPath in pairs(effectPathArray[idx] or {}) do
local uiEffect = self:CreateUiEffect(model, id, rootName, effectPath)
uiEffectArray[#uiEffectArray + 1] = uiEffect
end
end
return uiEffectArray
end
--- 获取Ui角色武器特效
--------------------------
function XUiPanelRoleModel:GetModelUiEquipEffect(model, id, rootName2EffectPath)
self:SetCurrentUiEffectActive(model.UiEquipEffect, true)
if model.UiEquipEffect and model.CurrentUiEquipEffectId == id then
return model.UiEquipEffect
end
model.CurrentUiEquipEffectId = id
model.UiEquipEffect = self:ClearUiEffectList(model.UiEquipEffect)
local list = {}
for rootName, effectPathList in pairs(rootName2EffectPath or {}) do
for _, effectPath in ipairs(effectPathList or {}) do
table.insert(list, self:CreateUiEffect(model, id, rootName, effectPath))
end
end
model.UiEquipEffect = list
return list
end
--==============================--
--desc: 生成Ui角色动作特效
--==============================--
function XUiPanelRoleModel:CreateUiEffect(model, id, rootName, effectPath)
local parent -- 搜挂点
if not rootName or rootName == XCharacterUiEffectConfig.GetDefaultRootName() then
parent = model.Model.gameObject
else
parent = model.Model.gameObject:FindGameObject(rootName)
if not parent then
parent = model.Model.gameObject
end
end
local obj = CS.LoadHelper.InstantiateGameObject(effectPath)
obj.transform:SetParent(parent.transform, false)
obj.transform:SetLayerRecursively(parent.gameObject.layer)
--local fx = parent:LoadPrefab(effectPath, false)
-- 由于预制是在模型加载之后,需要再次添加阴影
if self.ShowShadow then
CS.XShadowHelper.AddShadow(obj.gameObject, true)
end
-- 只有不是三个模型同时出现的界面调用此接口 由于预制是在模型加载之后,需要再次添加阴影
if not self.FixLight then
CS.XShadowHelper.SetCharRealtimeShadow(self.GameObject, true)
end
return obj
end
--动作播放完重新播放特效
function XUiPanelRoleModel:SetReActiveUiEffect(model)
--local playRoleAnimation = model.Model.gameObject:GetComponent("XPlayRoleAnimation")
if XTool.IsTableEmpty(model.UiEffect)
and XTool.IsTableEmpty(model.UiEquipEffect) --[[or not playRoleAnimation]] then
return
end
self:SetUiStandAnimaFinishCallback(model.Model, function()
for _, effect in ipairs(model.UiEffect or {}) do
if not XTool.UObjIsNil(effect) and effect.gameObject.activeSelf then
effect.gameObject:SetActiveEx(false)
effect.gameObject:SetActiveEx(true)
end
end
for _, effect in ipairs(model.UiEquipEffect or {}) do
if not XTool.UObjIsNil(effect) and effect.gameObject.activeSelf then
effect.gameObject:SetActiveEx(false)
effect.gameObject:SetActiveEx(true)
end
end
end, nil, false, false)
--playRoleAnimation:SetIsNotRemoveFinishCallback(true)
--playRoleAnimation:SetFinishedCallback(function()
-- for _, effect in ipairs(effectList or {}) do
-- if not XTool.UObjIsNil(effect) and effect.gameObject.activeSelf then
-- effect.gameObject:SetActiveEx(false)
-- effect.gameObject:SetActiveEx(true)
-- end
-- end
--end)
end
function XUiPanelRoleModel:SetCurrentUiEffectActive(effectList, isActive)
if XTool.IsTableEmpty(effectList) then
return
end
for _, effect in ipairs(effectList or {}) do
if not XTool.UObjIsNil(effect) then
effect.gameObject:SetActiveEx(isActive)
end
end
end
function XUiPanelRoleModel:ClearUiEffectList(effectList)
for _, effect in ipairs(effectList or {}) do
if not XTool.UObjIsNil(effect) then
XUiHelper.Destroy(effect)
end
end
return {}
end
function XUiPanelRoleModel:GetValidEffect(effectList)
local list = {}
for _, effect in ipairs(effectList or {}) do
if not XTool.UObjIsNil(effect) then
table.insert(list, effect)
end
end
return list
end
--endregion------------------------------------加载Ui角色动作特效end---------------------------
--==============================--
--desc: 更新角色模型
--@characterId: 角色id
--@targetPanelRole: 目标面板
--@targetUiName: 目标ui名
--==============================--
function XUiPanelRoleModel:UpdateCharacterModel(
characterId,
targetPanelRole,
targetUiName,
cb,
weaponCb,
fashionId,
growUpLevel,
hideEffect,
isShowDefaultWeapon,
isNotSelf)
self.StandAnimaShowWeaponList = {}
local weaponFashionId
if XRobotManager.CheckIsRobotId(characterId) then
local robotId = characterId
characterId = XRobotManager.GetRobotTemplate(characterId).CharacterId
weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
end
local resourcesId
if XTool.IsNumberValid(fashionId) then
resourcesId = XDataCenter.FashionManager.GetResourcesId(fashionId)
self.NowFashionId = fashionId
else
resourcesId = XDataCenter.FashionManager.GetFashionResourceIdByCharId(characterId)
self.NowFashionId = XDataCenter.FashionManager.GetFashionIdByResId(resourcesId)
end
local modelName
if resourcesId then
modelName = XDataCenter.CharacterManager.GetCharResModel(resourcesId)
else
modelName = self:GetModelName(characterId)
end
if not modelName then
return
end
self.IsStandAnimaShowWeapon = XDataCenter.EquipManager.CheckHasLoadEquipBySignboard(characterId, self.NowFashionId)
self:SetCueId(self.NowFashionId)
self:UpdateRoleModel(modelName, targetPanelRole, targetUiName,
function(model)
if not self.HideWeapon then
self:UpdateCharacterWeaponModels(characterId, modelName, weaponCb, hideEffect, nil, weaponFashionId, isShowDefaultWeapon) --- todo cur equip
end
if self.IsStandAnimaShowWeapon and self.HideWeapon then
local equipUsage = XDataCenter.EquipManager.GetEquipAnimControllerBySignboard(characterId, self.NowFashionId)
local newCb = function(model)
self.StandAnimaShowWeaponList[#self.StandAnimaShowWeaponList + 1] = model
if weaponCb then
weaponCb(model)
end
end
self:UpdateCharacterWeaponModels(characterId, modelName, newCb, hideEffect, nil, weaponFashionId, isShowDefaultWeapon, equipUsage)
end
if not hideEffect then
self:UpdateCharacterLiberationLevelEffect(modelName, characterId, growUpLevel, fashionId)
end
if cb then
cb(model)
end
if self.FixLight then
CS.XGraphicManager.FixUICharacterLightDir(model.gameObject)
end
end)
local actionId = self:GetPlayingStateName(AnimeLayer.Body)
self:LoadCharacterUiEffect(tonumber(characterId), actionId, isNotSelf, weaponFashionId, isShowDefaultWeapon)
end
---将callback保存在列表中在执行回调时遍历callback列表
---@param model UnityEngine.GameObject 角色模型
---@param callback function 回调函数
---@param disableCallback function 模型销毁的回调
---@param isOnce boolean 是否只执行一次
---@param isInstantExecute boolean 是否立即执行
function XUiPanelRoleModel:SetUiStandAnimaFinishCallback(model, callback, disableCallback, isOnce, isInstantExecute)
isOnce = isOnce or false
isInstantExecute = isInstantExecute or false
self.UiStandCallBack[#self.UiStandCallBack + 1] = { Callback = callback, IsOnce = isOnce }
local playAnima = model.gameObject:GetComponent(typeof(CS.XPlayRoleAnimation))
if not playAnima then
return
end
if isInstantExecute then
callback()
end
playAnima:SetIsNotRemoveFinishCallback(true)
playAnima:SetFinishedCallback(function()
for i = #self.UiStandCallBack, 1, -1 do
local funcData = self.UiStandCallBack[i]
local callbackFunc = funcData.Callback
local isOnlyOnce = funcData.IsOnce
callbackFunc()
if isOnlyOnce then
table.remove(self.UiStandCallBack, i)
end
end
end)
if disableCallback ~= nil then
playAnima:SetDisableCallback(disableCallback)
end
end
function XUiPanelRoleModel:SetCueId(fashionId)
if not fashionId then
return
end
self.UiStandCallBack = {}
self.CueId = XDataCenter.FashionManager.GetCueIdByFashionId(fashionId)
end
--==============================--
--desc: 在查看其他玩家信息时,更新角色模型
--==============================--
function XUiPanelRoleModel:UpdateCharacterModelOther(
character,
weapon,
weaponFashionId,
targetPanelRole,
targetUiName,
cb)
local characterId = character.Id
if XRobotManager.CheckIsRobotId(characterId) then
local robotId = characterId
characterId = XRobotManager.GetRobotTemplate(characterId).CharacterId
weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
end
local template = XDataCenter.FashionManager.GetFashionTemplate(character.FashionId)
local resourcesId = template.ResourcesId
local modelName
if resourcesId then
modelName = XDataCenter.CharacterManager.GetCharResModel(resourcesId)
else
local quality
if character then
quality = character.Quality
end
modelName = XDataCenter.CharacterManager.GetCharModel(characterId, quality)
end
if not modelName then
return
end
self:UpdateRoleModel(
modelName,
targetPanelRole,
targetUiName,
function(model)
if not self.HideWeapon then
self:UpdateCharacterWeaponModelsOther(character, weapon, weaponFashionId, modelName)
end
local fashionId = character.FashionId or XCharacterConfigs.GetCharacterTemplate(character.Id).DefaultNpcFashtionId
self:UpdateCharacterLiberationLevelEffect(modelName, characterId, character.LiberateLv, fashionId)
if cb then
cb(model)
end
if self.FixLight then
CS.XGraphicManager.FixUICharacterLightDir(model.gameObject)
end
end
)
self:LoadCharacterUiEffectOther(character, nil, weapon, weaponFashionId)
end
function XUiPanelRoleModel:LoadCharacterUiEffectOther(character, actionId, weapon, weaponFashionId)
if not character then
return
end
local fashionId = character.FashionId or XCharacterConfigs.GetCharacterTemplate(character.Id).DefaultNpcFashtionId
local id, rootName, effectPath = XCharacterUiEffectConfig.GetEffectInfo(character.Id, fashionId, actionId)
local model = self.RoleModelPool[self.CurRoleName]
if not model.CharacterId then
model.CharacterId = character.Id
end
self:SetCurrentUiEffectActive(model.UiEffect, false)
self:SetCurrentUiEffectActive(model.UiEquipEffect, false)
if not model.NotUiStand1 then
local playRoleAnimation = model.Model.gameObject:GetComponent("XPlayRoleAnimation")
if playRoleAnimation then
local defaultAnimeName = playRoleAnimation.DefaultClip
model.NotUiStand1 = defaultAnimeName ~= "UiStand1"
else
model.NotUiStand1 = true
return
end
end
if not actionId and model.NotUiStand1 then
return
end
if not actionId then
model.UiDefaultId = id
end
self:LoadCharacterUiEquipEffectOther(model, weapon, fashionId, actionId, weaponFashionId)
self:PlayCharacterUiEffect(model, id, rootName, effectPath)
end
--==============================--
--desc: 更新机器人角色模型
--==============================--
function XUiPanelRoleModel:UpdateRobotModel(robotId, characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController
, targetPanelRole, targetUiName)
local resourcesId
local nowFashionId
if fashionId then
resourcesId = XDataCenter.FashionManager.GetResourcesId(fashionId)
nowFashionId = fashionId
else
resourcesId = XDataCenter.FashionManager.GetFashionResourceIdByCharId(characterId)
nowFashionId = XDataCenter.FashionManager.GetFashionIdByResId(resourcesId)
end
local modelName
if resourcesId then
modelName = XDataCenter.CharacterManager.GetCharResModel(resourcesId)
else
modelName = self:GetModelName(characterId)
end
if not modelName then
return
end
targetUiName = targetUiName or self.RefName
local weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
self:SetCueId(nowFashionId)
self:UpdateRoleModel(modelName, targetPanelRole, targetUiName, function(model)
if not self.HideWeapon then
self:UpdateCharacterWeaponModels(characterId, modelName, weaponCb, true, equipTemplateId, weaponFashionId)
end
if modelCb then
modelCb(model)
end
if self.FixLight then
CS.XGraphicManager.FixUICharacterLightDir(model.gameObject)
end
end, nil, needDisplayController)
self:LoadResCharacterUiEffect(characterId, fashionId, weaponFashionId, nil, equipTemplateId)
end
--==============================--
--desc: 更新机器人角色模型 可以根据UseFashion使用角色涂装和角色武器涂装
--==============================--
function XUiPanelRoleModel:UpdateRobotModelNew(robotId, characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController, targetPanelRole, targetUiName)
local weaponFashionId
local isOwn = XDataCenter.CharacterManager.IsOwnCharacter(characterId)
if XRobotManager.CheckUseFashion(robotId) and isOwn then
local character = XDataCenter.CharacterManager.GetCharacter(characterId)
local robot2CharViewModel = character:GetCharacterViewModel()
fashionId = robot2CharViewModel:GetFashionId()
weaponFashionId = XDataCenter.WeaponFashionManager.GetCharacterWearingWeaponFashionId(characterId)
else
weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
end
self:UpdateRobotModelPublicNew(weaponFashionId,characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController, targetPanelRole, targetUiName)
end
--==============================--
--desc: 更新机器人角色模型 可以手动设置角色武器。武器涂装以机器人优先
--==============================--
function XUiPanelRoleModel:UpdateRobotModelWithWeapon(robotId, characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController, targetPanelRole, targetUiName)
local weaponFashionId
local isOwn = XDataCenter.CharacterManager.IsOwnCharacter(characterId)
if XRobotManager.CheckUseFashion(robotId) and isOwn then
local character = XDataCenter.CharacterManager.GetCharacter(characterId)
local robot2CharViewModel = character:GetCharacterViewModel()
fashionId = robot2CharViewModel:GetFashionId()
weaponFashionId = XDataCenter.WeaponFashionManager.GetCharacterWearingWeaponFashionId(characterId)
else
weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
end
if not XTool.IsNumberValid(weaponFashionId) then
weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
end
self:UpdateRobotModelPublicNew(weaponFashionId,characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController, targetPanelRole, targetUiName)
end
--==============================--
--desc: 更新机器人角色模型 模型新显示逻辑的公共部分
--==============================--
function XUiPanelRoleModel:UpdateRobotModelPublicNew(weaponFashionId,characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController, targetPanelRole, targetUiName)
local resourcesId
if fashionId then
resourcesId = XDataCenter.FashionManager.GetResourcesId(fashionId)
else
resourcesId = XDataCenter.FashionManager.GetFashionResourceIdByCharId(characterId)
end
local modelName
if resourcesId then
modelName = XDataCenter.CharacterManager.GetCharResModel(resourcesId)
else
modelName = self:GetModelName(characterId)
end
if not modelName then
return
end
self:UpdateRoleModel(modelName, targetPanelRole, targetUiName, function(model)
if not self.HideWeapon then
self:UpdateCharacterWeaponModels(characterId, modelName, weaponCb, true, equipTemplateId, weaponFashionId)
end
if modelCb then
modelCb(model)
end
if self.FixLight then
CS.XGraphicManager.FixUICharacterLightDir(model.gameObject)
end
end, nil, needDisplayController)
self:LoadResCharacterUiEffect(characterId, fashionId, weaponFashionId, nil, equipTemplateId)
end
function XUiPanelRoleModel:UpdateCharacterResModel(resId, characterId, targetUiName, cb, growUpLevel, weaponFashionId)
local modelName = XDataCenter.CharacterManager.GetCharResModel(resId)
local fashionId = XDataCenter.FashionManager.GetFashionIdByResId(resId)
if modelName then
self:SetCueId(fashionId)
self:UpdateRoleModel(modelName, nil, targetUiName, function(model)
if not self.HideWeapon then
self:UpdateCharacterWeaponModels(characterId, modelName, nil, nil, nil, weaponFashionId)
end
self:UpdateCharacterLiberationLevelEffect(modelName, characterId, growUpLevel, fashionId)
if cb then
cb(model)
end
end
)
end
if fashionId then
self:LoadResCharacterUiEffect(characterId, fashionId, weaponFashionId)
end
end
function XUiPanelRoleModel:UpdateCharacterModelByModelId(
modelId,
characterId,
targetPanelRole,
targetUiName,
cb,
growUpLevel,
showDefaultFx)
if not modelId then
return
end
self:UpdateRoleModel(modelId, targetPanelRole, targetUiName, function(model)
if not self.HideWeapon then
self:UpdateCharacterWeaponModels(characterId, modelId)
end
self:UpdateCharacterLiberationLevelEffect(modelId, characterId, growUpLevel, nil, showDefaultFx)
if cb then
cb(model)
end
end)
local defaultFashionId = XCharacterConfigs.GetCharacterTemplate(characterId).DefaultNpcFashtionId
local fashionId
if growUpLevel == 2 then --growUpLevel 2为第一套解放衣服 34为第二套解放衣服解放的时装Id跟默认时装Id紧挨且按顺序+1
fashionId = defaultFashionId + 1
elseif growUpLevel >= 3 then
fashionId = defaultFashionId + 2
else
fashionId = defaultFashionId
end
if fashionId then
self:LoadResCharacterUiEffect(characterId, fashionId)
end
end
function XUiPanelRoleModel:UpdateBossModel(modelName, targetUiName, targetPanelRole, cb, isReLoad)
if modelName then
self:UpdateRoleModel(
modelName,
targetPanelRole,
targetUiName,
function(model)
if cb then
cb(model)
end
end,
true
)
end
end
function XUiPanelRoleModel:UpdateArchiveMonsterModel(modelName, targetUiName, targetPanelRole, cb)
if modelName then
self:UpdateRoleModel(
modelName,
targetPanelRole,
targetUiName,
function(model)
if cb then
cb(model)
end
end,
true
)
end
end
local DoPartnerModelControl = function(modelName, model) -- 加载伙伴模型时同时加载“模型节点控制”配置
local modelControlList = XPartnerConfigs.GetPartnerModelControlsByModel(modelName)
if modelControlList then
for nodeName, modelControl in pairs(modelControlList) do
local parts
if nodeName == XPartnerConfigs.DefaultNodeName then
parts = model.transform
else
parts = model.gameObject:FindTransform(nodeName)
end
if not XTool.UObjIsNil(parts) then
if modelControl.IsHide and modelControl.IsHide == 1 then
parts.gameObject:SetActiveEx(false)
end
if modelControl.Effect and not string.IsNilOrEmpty(modelControl.Effect) then
local effect = parts.gameObject:LoadPrefab(modelControl.Effect, false)
if effect then
effect.gameObject:SetActiveEx(true)
end
end
else
XLog.Error("NodeName Is Wrong :" .. nodeName)
end
end
end
end
function XUiPanelRoleModel:UpdatePartnerModel(
modelName,
targetUiName,
targetPanelRole,
cb,
isReLoad,
needController,
IsReLoadController)
if modelName then
self:UpdateRoleModel(
modelName,
targetPanelRole,
targetUiName,
function(model)
if cb then
cb(model)
end
self:LoadPartnerUiEffect(modelName, XPartnerConfigs.EffectParentName.ModelLoopEffect, false, false)
--DoPartnerModelControl(modelName, model)
end,
isReLoad,
needController,
IsReLoadController
)
end
end
function XUiPanelRoleModel:UpdateSCBattleShowModel(
modelName,
weaponIdList,
targetUiName,
targetPanelRole,
cb,
isReLoad,
needController,
IsReLoadController)
if modelName then
self:UpdateRoleModel(modelName, targetPanelRole, targetUiName, function(model)
if cb then
cb(model)
end
XModelManager.LoadRoleWeaponModel(model, weaponIdList,
self.RefName, nil, false, self.GameObject, modelName)
end, isReLoad, false, IsReLoadController, needController)
end
end
function XUiPanelRoleModel:UpdateCharacterModelByFightNpcData(fightNpcData, cb, isCute, needDisplayController,customizeWeaponData)
local char = fightNpcData.Character
if char then
local modelName
local fashionId = char.FashionId
if isCute then
modelName = XCharacterCuteConfig.GetCuteModelModelName(char.Id)
elseif fashionId then
local fashion = XDataCenter.FashionManager.GetFashionTemplate(fashionId)
modelName = XDataCenter.CharacterManager.GetCharResModel(fashion.ResourcesId)
else
-- modelName = XDataCenter.CharacterManager.GetCharModel(char.Id, char.Quality)
modelName = self:GetModelName(char.Id)
end
if modelName then
self:SetCueId(fashionId)
self:UpdateRoleModel(modelName, nil, nil, function(model)
self:UpdateEquipsModelsByFightNpcData(model, fightNpcData, modelName)
self:UpdateCharacterLiberationLevelEffect(modelName, char.Id, char.LiberateLv, fashionId)
if cb then
cb(model)
end
if isCute then
self:CloseRootMotion(model)
end
end,nil, needDisplayController)
end
if isCute then
self:LoadCharacterCuteUiEffect(char.Id)
elseif customizeWeaponData then
self:LoadResCharacterUiEffect(char.Id, fashionId, fightNpcData.WeaponFashionId, nil, fightNpcData.Equips[1].TemplateId)
else
self:LoadResCharacterUiEffect(char.Id, fashionId)
end
end
end
function XUiPanelRoleModel:UpdateEquipsModelsByFightNpcData(charModel, fightNpcData, modelName)
XModelManager.LoadRoleWeaponModelByFight(charModel, fightNpcData, self.RefName, self.GameObject, modelName)
end
--==============================--
--desc: 更新角色武器模型
--@characterId: 角色id
--==============================--
function XUiPanelRoleModel:UpdateCharacterWeaponModels(
characterId,
modelName,
weaponCb,
hideEffect,
equipTemplateId,
weaponFashionId,
isShowDefaultWeapon,
equipUsage)
local equipModelIdList = {}
if equipTemplateId then
local equip = { TemplateId = equipTemplateId }
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByEquipData(equip, weaponFashionId)
else
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByCharacterId(characterId, isShowDefaultWeapon, weaponFashionId)
end
if not equipModelIdList or not next(equipModelIdList) then
return
end
if not modelName then
modelName = self:GetModelName(characterId)
end
local roleModel = self.RoleModelPool[modelName]
if not roleModel then
return
end
local weaponModelList = {}
local tempWeaponCb = function(weaponModel)
weaponModelList[#weaponModelList + 1] = weaponModel
if weaponCb then
weaponCb(weaponModel)
end
end
XModelManager.LoadRoleWeaponModel(
roleModel.Model,
equipModelIdList,
self.RefName,
tempWeaponCb,
hideEffect,
self.GameObject,
modelName,
equipUsage
)
self:WeaponAnimationSync(weaponModelList, modelName)
end
--==============================--
--desc: 查看其他玩家角色信息时,更新角色武器模型
--==============================--
function XUiPanelRoleModel:UpdateCharacterWeaponModelsOther(
characterId,
equip,
weaponFashionId,
modelName,
weaponCb,
hideEffect)
local equipModelIdList = {}
if weaponFashionId and weaponFashionId ~= 0 then
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByEquipData(equip, weaponFashionId)
else
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByEquipData(equip)
end
if not equipModelIdList or not next(equipModelIdList) then
return
end
if not modelName then
modelName = self:GetModelName(characterId)
end
local roleModel = self.RoleModelPool[modelName]
if not roleModel then
return
end
XModelManager.LoadRoleWeaponModel(
roleModel.Model,
equipModelIdList,
self.RefName,
weaponCb,
hideEffect,
self.GameObject,
modelName
)
end
---=================================================
--- 在当前播放中的动画播放完后执行回调
--- 如果动画被打断或是停止都会调用回调
---@overload fun(callBack:function)
---@param callBack function
---=================================================
local CheckAnimeFinish = function(animator, behaviour, animaName, callBack, layer)
local animatorInfo = animator:GetCurrentAnimatorStateInfo(layer)
if (animatorInfo:IsName(animaName) and animatorInfo.normalizedTime >= 1) or not animatorInfo:IsName(animaName) then --normalizedTime的值为0~10为开始1为结束。
if callBack then
callBack()
end
behaviour.enabled = false
end
end
local AddPlayingAnimCallBack = function(obj, animator, animaName, callBack, layer)
local animatorInfo = animator:GetCurrentAnimatorStateInfo(layer)
if not animatorInfo:IsName(animaName) or animatorInfo.normalizedTime >= 1 then --normalizedTime的值0为开始大于1为结束。
return
end
local behaviour = obj.Transform:GetComponent(typeof(CS.XLuaBehaviour))
if not behaviour then
behaviour = obj.GameObject:AddComponent(typeof(CS.XLuaBehaviour))
else
behaviour.enabled = true
end
behaviour.LuaUpdate = function()
CheckAnimeFinish(animator, behaviour, animaName, callBack, layer)
end
end
---=================================================
--- 播放'AnimaName'动画fromBegin决定动画是否需要调整到从0开始播放默认值为false
---@overload fun(AnimaName:string)
---@param AnimaName string
---@param fromBegin boolean
---@param callBack function 成功之后的回调
---@param errorCb function 失败之后的回调
---@param layer number 状态机层级
---=================================================
function XUiPanelRoleModel:PlayAnima(AnimaName, fromBegin, callBack, errorCb, layer)
local animatorlaye = layer or 0
local IsCanPlay, animator = self:CheckAnimaCanPlay(AnimaName)
local delay = 1
if IsCanPlay and animator then
if fromBegin then
animator:Play(AnimaName, animatorlaye, 0)
else
animator:Play(AnimaName, animatorlaye)
end
local isLoadWeapon = self:PlayWeaponAnima(AnimaName, animator, delay, callBack, animatorlaye)
if callBack and not isLoadWeapon then
XScheduleManager.ScheduleOnce(function()
AddPlayingAnimCallBack(self, animator, AnimaName, callBack, animatorlaye)
end, delay)
end
else
if errorCb then
errorCb()
end
end
return IsCanPlay
end
---=================================================
--- 播放'AnimaName'动画fromBegin决定动画是否需要调整到从0开始播放默认值为false
---@overload fun(AnimaName:string)
---@param AnimaName string
---@param fromBegin boolean
---@param callBack function 成功之后的回调
---@param errorCb function 失败之后的回调
---@param layer number 状态机层级
---=================================================
function XUiPanelRoleModel:PlayAnimaCross(AnimaName, fromBegin, callBack, errorCb, layer)
local animatorlaye = layer or 0
local IsCanPlay, animator = self:CheckAnimaCanPlay(AnimaName)
if IsCanPlay and animator then
local delay = 0.25
if fromBegin then
--animator:Play(AnimaName, animatorlaye, 0)
animator:CrossFadeInFixedTime(AnimaName, delay, animatorlaye, 0)
else
animator:CrossFadeInFixedTime(AnimaName, delay, animatorlaye)
--animator:Play(AnimaName, animatorlaye)
end
local isLoadWeapon = self:PlayWeaponAnima(AnimaName, animator, delay * 1000 + 1, callBack, animatorlaye)
if callBack and not isLoadWeapon then
XScheduleManager.ScheduleOnce(function()
AddPlayingAnimCallBack(self, animator, AnimaName, callBack, animatorlaye)
end, delay * 1000 + 1)
end
else
if errorCb then
errorCb()
end
end
return IsCanPlay
end
function XUiPanelRoleModel:PlayWeaponAnima(actionId, animator, delay, callBack, animatorLayer)
local weaponModelList = self.StandAnimaShowWeaponList
local isStandAnimaShowWeapon = self.IsStandAnimaShowWeapon
local newCallBack = function()
for i = 1, #weaponModelList do
weaponModelList[i].gameObject:SetActiveEx(isStandAnimaShowWeapon)
end
if callBack then
callBack()
end
end
if not isStandAnimaShowWeapon then
weaponModelList = self:LoadWeaponModelWhenPlayAnima(actionId)
if weaponModelList then
XScheduleManager.ScheduleOnce(function()
for i = 1, #weaponModelList do
weaponModelList[i].gameObject:SetActiveEx(true)
end
AddPlayingAnimCallBack(self, animator, actionId, newCallBack, animatorLayer)
end, delay)
return true
end
return false
end
if not self:CheckHasLoadEquipWhenPlayAnima(actionId) and isStandAnimaShowWeapon then
XScheduleManager.ScheduleOnce(function()
for i = 1, #self.StandAnimaShowWeaponList do
self.StandAnimaShowWeaponList[i].gameObject:SetActiveEx(false)
end
AddPlayingAnimCallBack(self, animator, actionId, newCallBack, animatorLayer)
end, delay)
return true
end
return false
end
function XUiPanelRoleModel:CheckHasLoadEquipWhenPlayAnima(actionId)
local modelName = self.CurRoleName
if not modelName then
return false
end
local characterId = self.RoleModelPool[modelName].CharacterId
if not characterId then
return false
end
local fashionId = self.NowFashionId or XDataCenter.CharacterManager.GetShowFashionId(characterId)
if not fashionId then
return false
end
return XDataCenter.EquipManager.CheckHasLoadEquipBySignboard(characterId, fashionId, actionId)
end
function XUiPanelRoleModel:LoadWeaponModelWhenPlayAnima(actionId)
local modelName = self.CurRoleName
if not modelName then
return
end
local characterId = self.RoleModelPool[modelName].CharacterId
if not characterId then
return
end
local weaponFashionId = XDataCenter.WeaponFashionManager.GetCharacterWearingWeaponFashionId(characterId)
local roleModel = self.RoleModelPool[modelName].Model
local equipModelIdList = {}
local equipUsage = nil
local weaponModelList = {}
local weaponCb = function(model)
weaponModelList[#weaponModelList + 1] = model
end
equipModelIdList = XDataCenter.EquipManager.GetEquipModelIdListByCharacterId(characterId, false, weaponFashionId)
equipUsage = XDataCenter.EquipManager.GetEquipAnimControllerBySignboard(characterId, self.NowFashionId, actionId)
--equipUsage = 1
if not equipModelIdList or not next(equipModelIdList) or not roleModel or not equipUsage then
return
end
XModelManager.LoadRoleWeaponModel(roleModel, equipModelIdList, self.RefName, weaponCb, false, self.GameObject, modelName, equipUsage)
return weaponModelList
end
---=================================================
--- 播放身体动画状态机层级0
---@overload fun(AnimaName:string)
---@param AnimaName string
---@param fromBegin boolean
---@param callBack function 成功之后的回调
---@param errorCb function 失败之后的回调
---=================================================
function XUiPanelRoleModel:PlayBodyAnima(AnimaName, fromBegin, callBack, errorCb)
self:PlayAnima(AnimaName, fromBegin, callBack, errorCb, AnimeLayer.Body)
end
---=================================================
--- 播放表情动画状态机层级1
---@overload fun(AnimaName:string)
---@param AnimaName string
---@param fromBegin boolean
---@param callBack function 成功之后的回调
---@param errorCb function 失败之后的回调
---=================================================
function XUiPanelRoleModel:PlayFaceAnima(AnimaName, fromBegin, callBack, errorCb)
self:PlayAnima(AnimaName, fromBegin, callBack, errorCb, AnimeLayer.Face)
end
---=================================================
--- 检查'AnimaName'动画,是否能够播放
---@overload fun(AnimaName:string)
---@param AnimaName string
---=================================================
function XUiPanelRoleModel:CheckAnimaCanPlay(AnimaName)
local IsCanPlay = false
local animator
if self.CurRoleName and self.RoleModelPool[self.CurRoleName] and self.RoleModelPool[self.CurRoleName].Model then
animator = self.RoleModelPool[self.CurRoleName].Model:GetComponent("Animator")
if XModelManager.CheckAnimatorAction(animator, AnimaName) then
IsCanPlay = true
end
end
return IsCanPlay, animator
end
---=================================================
--- 无参数时,结束播放当前动画,恢复成站立动画
---
--- 有参数时,只有当前动画为'oriAnima',才结束播放动画
---@overload fun()
---@param oriAnima string
---=================================================
function XUiPanelRoleModel:StopAnima(oriAnima, force)
local animator = self.RoleModelPool[self.CurRoleName].Model:GetComponent("Animator")
local clips = animator:GetCurrentAnimatorClipInfo(0)
local clip
if clips and clips.Length > 0 then
clip = clips[0].clip
end
-- 是否需要播放动作打断特效
if self.PlayEffectFunc then
self.PlayEffectFunc()
end
if force and clip or oriAnima == nil or (clip and clip.name == oriAnima) then
-- 停止UI特效
self.CurrentAnimationName = nil
local model = self.RoleModelPool[self.CurRoleName]
self:SetCurrentUiEffectActive(model.UiEffect, false)
self:SetCurrentUiEffectActive(model.UiEquipEffect, false)
animator:Play(clip.name, 0, 0.999)
end
end
---@return UnityEngine.Animator
function XUiPanelRoleModel:GetAnimator()
local model = self.RoleModelPool[self.CurRoleName]
if not model then
return nil
end
if not XTool.UObjIsNil(model.Model) then
return model.Model:GetComponent("Animator")
else
return nil
end
end
function XUiPanelRoleModel:GetComponent(componentType)
if self.RoleModelPool[self.CurRoleName] then
return self.RoleModelPool[self.CurRoleName].Model:GetComponent(componentType)
else
return nil
end
end
function XUiPanelRoleModel:ShowRoleModel()
if not XTool.UObjIsNil(self.GameObject) then
self.GameObject:SetActiveEx(true)
end
end
function XUiPanelRoleModel:HideRoleModel()
if not XTool.UObjIsNil(self.GameObject) then
self.GameObject:SetActiveEx(false)
end
end
function XUiPanelRoleModel:SetModelZeroPos()
local model = self.RoleModelPool[self.CurRoleName].Model
if not model then return end
model.transform.localPosition = CS.UnityEngine.Vector3.zero
end
--- 获取正在播放动画名
---@param layerIndex number 状态机层级
---@return string
--------------------------
function XUiPanelRoleModel:GetPlayingStateName(layerIndex)
local animator = self:GetAnimator()
if XTool.UObjIsNil(animator) then
return
end
if XTool.UObjIsNil(animator.runtimeAnimatorController) then
return
end
local actionId
local clips = animator.runtimeAnimatorController.animationClips
local info = animator:GetCurrentAnimatorStateInfo(layerIndex)
for i = 0, clips.Length - 1 do
local clip = clips[i]
if info:IsName(clip.name) then
actionId = clip.name
break
end
end
return actionId
end
--==============================--
--desc: 更新角色解放特效
--@characterId: 角色id
--==============================--
function XUiPanelRoleModel:UpdateCharacterLiberationLevelEffect(
modelName,
characterId,
growUpLevel,
fashionId,
showDefaultFx)
local modelInfo
local isSpecialModel, _ = XModelManager.CheckModelIsSpecial(modelName)
if isSpecialModel then
if self.NewPanel then
modelName = XModelManager.GetMinorModelId(modelName)
modelInfo = modelName and self.NewPanel.RoleModelPool[modelName]
else
modelName = XModelManager.GetSpecialModelId(modelName)
modelInfo = self.RoleModelPool[modelName]
end
else
modelInfo = self.RoleModelPool[modelName]
end
local model = modelInfo and modelInfo.Model
if not model then
return
end
local liberationFx = modelInfo.LiberationFx
local character = XDataCenter.CharacterManager.GetCharacter(characterId)
local rootName, fxPath, aureoleId
if showDefaultFx then
--通过解放等级获取默认解放特效配置
rootName, fxPath = XDataCenter.CharacterManager.GetCharLiberationLevelEffectRootAndPath(characterId, growUpLevel)
else
-- 1.如果没有通过超解自定义手环
--通过角色Id获取时装对应解放特效配置
rootName, fxPath = XDataCenter.CharacterManager.GetCharFashionLiberationEffectRootAndPath(characterId, growUpLevel, fashionId)
aureoleId = character and XFashionConfigs.GetFashionCfgById(fashionId or character.FashionId).AureoleId
fxPath = XFashionConfigs.GetAureoleEffectPathById(aureoleId)
-- 2.如果有自定义手环
local currLiberateAureoleId = character and character.LiberateAureoleId
if XTool.IsNumberValid(currLiberateAureoleId) then
fxPath = XFashionConfigs.GetAureoleEffectPathById(currLiberateAureoleId)
liberationFx = nil -- 销毁替换之前的 刷新终解环
end
end
if not rootName or not fxPath then
if liberationFx then
liberationFx:SetActiveEx(false)
end
return
end
if not liberationFx then
local rootTransform = model.transform:FindTransform(rootName)
if XTool.UObjIsNil(rootTransform) then
XLog.Error(
"XUiPanelRoleModel:UpdateCharacterLiberationLevelEffect Error:can Not find rootTransform in this model, rootName is:" ..
rootName
)
return
end
modelInfo.LiberationFx = rootTransform.gameObject:LoadPrefab(fxPath, false)
modelInfo.AureoleId = aureoleId
-- self:FixAurolePos(modelInfo.LiberationFx, characterId, modelInfo)
else
liberationFx:SetActiveEx(true)
end
end
-- 给外部切换终解特效的接口
function XUiPanelRoleModel:SetLiberationEffect(modelName, rootName, aureoleId, characterId)
if not aureoleId then
return
end
local modelInfo
local isSpecialModel, _ = XModelManager.CheckModelIsSpecial(modelName)
if isSpecialModel then
if self.NewPanel then
modelName = XModelManager.GetMinorModelId(modelName)
modelInfo = modelName and self.NewPanel.RoleModelPool[modelName]
else
modelName = XModelManager.GetSpecialModelId(modelName)
modelInfo = self.RoleModelPool[modelName]
end
else
modelInfo = self.RoleModelPool[modelName]
end
local model = modelInfo and modelInfo.Model
local rootTransform = model.transform:FindTransform(rootName)
local effectPath = XFashionConfigs.GetAureoleEffectPathById(aureoleId)
modelInfo.LiberationFx = rootTransform.gameObject:LoadPrefab(effectPath, false)
if modelInfo.LiberationFx then
modelInfo.LiberationFx:SetActiveEx(true)
modelInfo.AureoleId = aureoleId
-- self:FixAurolePos(modelInfo.LiberationFx, characterId, modelInfo)
end
end
-- 由于2.0版本 新增同一角色可佩戴不同角色的手环,需要进行位置修正
function XUiPanelRoleModel:FixAurolePos(auroeTrans, characterId, modelInfo)
local defaultFashionId = XCharacterConfigs.GetCharacterTemplate(characterId).DefaultNpcFashtionId
local aureoleId = XFashionConfigs.GetAllConfigs(XFashionConfigs.TableKey.Fashion)[defaultFashionId].AureoleId
local aureoleConfig = aureoleId and XFashionConfigs.GetAllConfigs(XFashionConfigs.TableKey.FashionAureole)[aureoleId]
local tempEffectGo = nil
local resource = nil
if modelInfo.TempEffectGo then
tempEffectGo = modelInfo.TempEffectGo
else
resource = CS.XResourceManager.Load(aureoleConfig.EffectPath)
tempEffectGo = CS.UnityEngine.Object.Instantiate(resource.Asset, auroeTrans.transform.parent)
end
local tempTrans = tempEffectGo.transform:GetChild(0)
-- 第一子物体同步
local targetFixTrans = auroeTrans.transform:GetChild(0)
local tempGoPostition = tempTrans.localPosition
local tempGoRotation = tempTrans.localEulerAngles
local targetPos = CS.UnityEngine.Vector3(tempGoPostition.x, tempGoPostition.y, 0)
local targetRotation = CS.UnityEngine.Vector3(tempGoRotation.x, tempGoRotation.y, tempGoRotation.z)
targetFixTrans.localPosition = targetPos
targetFixTrans.localEulerAngles = targetRotation
tempEffectGo:SetActiveEx(false)
tempEffectGo.name = "TempAuroe"
modelInfo.TempEffectGo = tempEffectGo
if resource then
CS.XResourceManager.Unload(resource)
end
end
---=================================================
--- 材质控制器相关特效需要跟模型绑定
---@param effect UnityEngine.GameObject
---=================================================
function XUiPanelRoleModel:BindEffect(effect)
if XTool.UObjIsNil(effect) then
return
end
if self.CurRoleName and self.RoleModelPool[self.CurRoleName] and self.RoleModelPool[self.CurRoleName].RenderingProxy then
self.RoleModelPool[self.CurRoleName].RenderingProxy:BindEffect(effect)
effect.gameObject:SetActiveEx(false)
effect.gameObject:SetActiveEx(true)
end
end
function XUiPanelRoleModel:BindEffectByModel(model)
if model.UiEffect then
for i = 1, #model.UiEffect do
self:BindEffect(model.UiEffect[i])
end
end
if model.UiEquipEffect then
for i = 1, #model.UiEquipEffect do
self:BindEffect(model.UiEquipEffect[i])
end
end
end
---=================================================
--- 设置LoadEffect接口最大加载特效数量默认最大是1
---=================================================
function XUiPanelRoleModel:SetEffectMaxCount(value)
self.EffectMaxCount = value
end
---=================================================
--- 加载特效可支持多次加载特效需要提前设置EffectMaxCount
---@param effectPath string 特效路径
---@param isBindEffect boolean 材质控制器相关特效和模型绑定
---=================================================
function XUiPanelRoleModel:LoopLoadEffect(effectPath, isBindEffect)
if not effectPath then
return
end
if isBindEffect == nil then
isBindEffect = false
end
if self.EffectMaxCount == nil then
self.EffectMaxCount = 1
end
if self.EffectingIndex == nil then
self.EffectingIndex = 0
end
local effectParentKey = self.EffectingIndex % self.EffectMaxCount
self:LoadEffect(effectPath, effectParentKey, isBindEffect, false)
self.EffectingIndex = self.EffectingIndex + 1
end
local CreateEffectParentName = function(name)
return name and string.format("Customize_%s", name) or "Default_EffectParent"
end
---=================================================
---根据PartnerUiEffect加载辅助机特效
---@param modelName string 辅助机模型名字(来自【PartnerModel.tab】StandbyModel/CombatModel字段)
---@param effectParentName string 生成一个前缀Customize_+ effectParentName的节点,特效将挂载在其下。(XPartnerConfigs.EffectParentName枚举)
---@param isBindEffect boolean|nil 材质控制器相关特效和模型绑定
---@param isDisableOldEffect boolean|nil 为true时UnActive指定节点名下挂载的特效
---@param isUseModelParent boolean|nil 为true时该特效节点挂载在模型下
---=================================================
function XUiPanelRoleModel:LoadPartnerUiEffect(modelName, effectParentName, isBindEffect, isDisableOldEffect, isUseModelParent)
if isDisableOldEffect then
self:HideEffectByParentName(effectParentName)
end
if not modelName then
return
end
if isBindEffect == nil then
isBindEffect = false
end
self.EffectParentDic = self.EffectParentDic or {}
self.EffectDic = self.EffectDic or {}
local parentName = CreateEffectParentName(effectParentName)
if isUseModelParent then
parentName = modelName .. parentName
end
local effectInfo = XDataCenter.PartnerManager.GetPartnerUiEffect(modelName, effectParentName)
local curModelInfo = self:GetModelInfoByName(self.CurRoleName)
local effectParent = self.EffectParentDic[parentName]
if not effectInfo then
return
end
if not curModelInfo or XTool.UObjIsNil(curModelInfo.Model) then
XLog.Error("获取模型失败!请检查模型是否加载成功!")
return
end
if effectInfo.BoneRootName then
local node = curModelInfo.Model.transform:FindTransform(effectInfo.BoneRootName)
if XTool.UObjIsNil(node) then
XLog.Error("找不到同名骨骼!骨骼名:" .. effectInfo.BoneRootName)
return
end
effectParent = node:FindTransform(parentName)
if XTool.UObjIsNil(effectParent) then
effectParent = CS.UnityEngine.GameObject(tostring(parentName))
effectParent.transform:SetParent(node, false)
end
else
if not effectParent or XTool.UObjIsNil(effectParent) then
local parentTransform = nil
if isUseModelParent or effectParentName == XPartnerConfigs.EffectParentName.ModelLoopEffect then
parentTransform = curModelInfo.Model.transform
else
parentTransform = self.Transform
end
effectParent = CS.UnityEngine.GameObject(tostring(parentName))
effectParent.transform:SetParent(parentTransform, false)
self.EffectParentDic[parentName] = effectParent
end
end
for i, effectPath in pairs(effectInfo.EffectPath) do
local effectNode = effectParent.transform:FindTransform(effectParentName .. i)
local effect = nil
if not effectNode or XTool.UObjIsNil(effectNode) then
effectNode = CS.UnityEngine.GameObject(effectParentName .. i)
effectNode.transform:SetParent(effectParent.transform, false)
end
effect = effectNode:LoadPrefab(effectPath)
self.EffectDic[parentName] = self.EffectDic[parentName] or {}
self.EffectDic[parentName][effectPath] = effect
if effect == nil or XTool.UObjIsNil(effect) then
XLog.Error("加载的特效为空! 路径:" .. effectPath)
return
end
if isBindEffect then
self:BindEffect(effect)
end
effectNode.gameObject:SetActiveEx(false)
effectNode.gameObject:SetActiveEx(true)
end
end
---=================================================
---生成指定名称的父节点并在其下加载特效
---@param effectPath string 特效路径
---@param effectParentName any 生成一个前缀Customize_+ effectParentName的节点,特效将挂载在其下。不指定时默认生成一个Default_EffectParent节点供挂载
---@param isBindEffect boolean|nil 材质控制器相关特效和模型绑定
---@param isDisableOldEffect boolean|nil 为true时UnActive指定节点名下挂载的特效
---@param isUseModelParent boolean|nil 为true时该特效节点挂载在模型下
---=================================================
function XUiPanelRoleModel:LoadEffect(effectPath, effectParentName, isBindEffect, isDisableOldEffect, isUseModelParent)
if isDisableOldEffect then
self:HideEffectByParentName(effectParentName)
end
if not effectPath then
return
end
if isBindEffect == nil then
isBindEffect = false
end
self.EffectParentDic = self.EffectParentDic or {}
self.EffectDic = self.EffectDic or {}
local parentName = CreateEffectParentName(effectParentName)
local effectParent = self.EffectParentDic[parentName]
if effectParent == nil then
local curModelInfo = self:GetModelInfoByName(self.CurRoleName)
local model
if curModelInfo then
model = curModelInfo.Model.transform
end
local parentTransform = isUseModelParent and model or self.Transform
effectParent = CS.UnityEngine.GameObject(tostring(parentName))
effectParent.transform:SetParent(parentTransform, false)
self.EffectParentDic[parentName] = effectParent
end
local effect = effectParent:LoadPrefab(effectPath)
self.EffectDic[parentName] = self.EffectDic[parentName] or {}
self.EffectDic[parentName][effectPath] = effect
if effect == nil or XTool.UObjIsNil(effect) then
XLog.Error(string.format("特效路径%s加载的特效为空", effectPath))
return
end
if isBindEffect then
self:BindEffect(effect)
end
effect.gameObject:SetActiveEx(false)
effect.gameObject:SetActiveEx(true)
end
---读取特效节点
function XUiPanelRoleModel:GetEffectObj(effectParentName, effectPath)
local parentName = CreateEffectParentName(effectParentName)
if XTool.IsTableEmpty(self.EffectDic) or XTool.IsTableEmpty(self.EffectDic[parentName]) then return end
return self.EffectDic[parentName][effectPath]
end
function XUiPanelRoleModel:HideEffectByParentName(effectParentName)
if self.EffectDic == nil then
return
end
local parentName = CreateEffectParentName(effectParentName)
for _, effect in pairs(self.EffectDic[parentName] or {}) do
if effect and not XTool.UObjIsNil(effect) then
effect.gameObject:SetActiveEx(false)
end
end
end
function XUiPanelRoleModel:HideAllEffects()
for _, effectGroup in pairs(self.EffectDic or {}) do
for _, effect in pairs(effectGroup or {}) do
if effect and not XTool.UObjIsNil(effect) then
effect.gameObject:SetActiveEx(false)
end
end
end
end
function XUiPanelRoleModel:GetModelInfoByName(name)
return self.RoleModelPool[name]
end
function XUiPanelRoleModel:RemoveRoleModelPool()
local modelPool = self.RoleModelPool
for _, modelInfo in pairs(modelPool or {}) do
if modelInfo.Model and modelInfo.Model:Exist() then
CS.UnityEngine.Object.Destroy(modelInfo.Model.gameObject)
end
end
self.RoleModelPool = {}
end
---=================================================
---更新Q版角色模型 参数都是复制自UpdateRobotModel
---希望以后统一通用接口,所以进行了二次封装并加上一定注解
---期待一个有缘人统一模型加载参数对象 by ljb
---@param robotId number|nil Robot.tab的robotId
---@param characterId number|nil Character.tab的characterId
---@param equipTemplateId number|nil Equip.tab的equipId
---@param weaponCb function|nil 武器模型加载后回调
---@param fashionId number|nil 模型皮肤id
---@param modelCb function|nil 武器模型加载后回调
---@param needDisplayController boolean
---@param targetPanelRole
---@param targetUiName
---=================================================
function XUiPanelRoleModel:UpdateCuteModel(robotId, characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController
, targetPanelRole, targetUiName)
if not characterId then
characterId = XRobotManager.GetCharacterId(robotId)
end
local modelName = XCharacterCuteConfig.GetCuteModelModelName(characterId)
local weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
self:UpdateCuteModelByModelName(characterId, fashionId, equipTemplateId, weaponFashionId, weaponCb, modelName,
modelCb, needDisplayController, targetPanelRole, targetUiName)
end
---=================================================
---更新Q版角色模型 UpdateCuteModel()的二次封装
---@param characterId number|nil
---@param fashionId number|nil
---@param equipTemplateId number|nil
---@param weaponFashionId number|nil
---@param weaponCb function|nil
---@param modelName string
---@param modelCb function|nil
---@param needDisplayController boolean
---@param targetPanelRole
---@param targetUiName
---=================================================
function XUiPanelRoleModel:UpdateCuteModelByModelName(characterId, fashionId, equipTemplateId, weaponFashionId, weaponCb, modelName
, modelCb, needDisplayController, targetPanelRole, targetUiName)
if not modelName or modelName == "" then
return
end
self:UpdateRoleModel(modelName, targetPanelRole, targetUiName, function(model)
if not self.HideWeapon and XTool.IsNumberValid(equipTemplateId) then
self:UpdateCharacterWeaponModels(
characterId,
modelName,
weaponCb,
true,
equipTemplateId,
weaponFashionId
)
end
if modelCb then
modelCb(model)
end
if self.FixLight then
CS.XGraphicManager.FixUICharacterLightDir(model.gameObject)
end
-- Q版模型禁止动画移动
self:CloseRootMotion(model)
end, nil, needDisplayController)
self:LoadCharacterCuteUiEffect(characterId)
end
-- 禁止动画根节点移动
function XUiPanelRoleModel:CloseRootMotion(model)
local animator = model:GetComponent("Animator")
animator.applyRootMotion = false
end
---=================================================
--- 播放'AnimaName'动画,融合过渡
---@overload fun(animaName:string)
---@param animaName string
---@param crossDuration number@两个动作的融合时长
---@param animatorLayer number@动画层
---=================================================
function XUiPanelRoleModel:CrossFadeAnim(animaName, crossDuration, animatorLayer)
local IsCanPlay, animator = self:CheckAnimaCanPlay(animaName)
if IsCanPlay and animator then
animator:CrossFade(animaName, crossDuration or 0.2, animatorLayer or 0)
end
return IsCanPlay
end
function XUiPanelRoleModel:GetCurRoleName()
return self.CurRoleName
end
---@param dataModel XDlcHuntModel
function XUiPanelRoleModel:UpdateDlcModel(dataModel, targetUiName, callback)
local characterId = nil
local weaponFashionId = nil
local weaponId = dataModel:GetWeaponId()
local modelName = dataModel:GetModelId()
local fashionId = nil
local targetPanelRole = nil
self:UpdateRoleModel(modelName, targetPanelRole, targetUiName, function(model)
if not weaponId then
if callback then callback() end
return
end
self:UpdateCharacterWeaponModels(characterId, modelName, callback, true, weaponId, weaponFashionId)
end, nil, nil)
self:LoadResCharacterUiEffect(characterId, fashionId, weaponFashionId)
end
-- 开启/关闭头部跟随
function XUiPanelRoleModel:SetXPostFaicalControllerActive(flag)
if not self.CurRoleName then
return
end
local curModelInfo = self:GetModelInfoByName(self.CurRoleName)
local model
if curModelInfo then
model = curModelInfo.Model.transform
end
if not model then
return
end
local targetComponent = model:GetComponent(typeof(CS.XPostFaicalController))
if not targetComponent then
return
end
targetComponent.enabled = true
targetComponent:ActiveInput(flag)
end
function XUiPanelRoleModel:SetLocalPosition(v3)
if not self.CurRoleName then
return
end
local curModelInfo = self.RoleModelPool[self.CurRoleName]
curModelInfo.Model.transform.localPosition = v3
end
function XUiPanelRoleModel:SetLocalRotation(v3)
if not self.CurRoleName then
return
end
local curModelInfo = self.RoleModelPool[self.CurRoleName]
curModelInfo.Model.transform.localEulerAngles = v3
end
function XUiPanelRoleModel:SetWorldPosition(v3)
if not self.CurRoleName then
return
end
local curModelInfo = self.RoleModelPool[self.CurRoleName]
curModelInfo.Model.transform.position = v3
end
function XUiPanelRoleModel:GetTransform()
if not self.CurRoleName then
return
end
local curModelInfo = self.RoleModelPool[self.CurRoleName]
return curModelInfo.Model.transform
end
-- 同步武器动画
function XUiPanelRoleModel:WeaponAnimationSync(weaponModelList, modelName)
if XTool.IsTableEmpty(weaponModelList) then
return
end
local isAnimReset = XEquipConfig.GetEquipAnimIsReset(modelName)
if not isAnimReset then
return
end
local roleModel = self.RoleModelPool[modelName]
if not roleModel or XTool.UObjIsNil(roleModel.Model.gameObject) then
return
end
local playRoleAnimation = roleModel.Model.gameObject:GetComponent("XPlayRoleAnimation")
if not playRoleAnimation then
return
end
local defaultAnimeName = playRoleAnimation.DefaultClip
if defaultAnimeName ~= "UiStand1" then
return
end
local defaultAnimeLength = 0
for i = 0, playRoleAnimation.Clips.Length - 1 do
local clip = playRoleAnimation.Clips[i]
if clip and clip.name == defaultAnimeName then
defaultAnimeLength = clip.length
break
end
end
playRoleAnimation:SetPlayCallback(function(leftTime)
local layerIndex = 0
for _, weaponModel in pairs(weaponModelList or {}) do
if XTool.UObjIsNil(weaponModel) then
goto CONTINUE
end
---@type UnityEngine.Animator
local weaponAnim = weaponModel:GetComponent("Animator")
if XTool.UObjIsNil(weaponAnim) or XTool.UObjIsNil(weaponAnim.runtimeAnimatorController) then
goto CONTINUE
end
local stateInfo = weaponAnim:GetCurrentAnimatorStateInfo(layerIndex)
local length = stateInfo.length
-- 角色动作时长和武器动作时长不一致时跳过武器动作重置
if length <= 0 or math.abs(defaultAnimeLength - length) > 0.05 then
goto CONTINUE
end
local time = leftTime / length
weaponAnim:Play(stateInfo.shortNameHash, layerIndex, time)
:: CONTINUE ::
end
end)
end
return XUiPanelRoleModel