PGRData/Script/matrix/xui/xuicharacter/XUiPanelRoleModel.lua

1569 lines
50 KiB
Lua
Raw Normal View History

---@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
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
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]
if IsReLoadAnime then
self:LoadModelAndReLoadAnime(
modelInfo,
targetUiName,
roleName,
defaultAnimation,
cb,
runtimeControllerName,
IsReLoadController
)
else
self:LoadModelAndNotReLoadAnime(
modelInfo,
targetUiName,
roleName,
defaultAnimation,
cb,
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
-- 阴影要放在武器模型加载完之后
if self.ShowShadow then
CS.XShadowHelper.AddShadow(self.GameObject)
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)
if not characterId then
return
end
local fashionId = XDataCenter.CharacterManager.GetShowFashionId(characterId, isNotSelf)
local id, rootName, effectPath = XCharacterUiEffectConfig.GetEffectInfo(characterId, fashionId, actionId)
local model = self.RoleModelPool[self.CurRoleName]
if not model.CharacterId then
model.CharacterId = characterId
end
self:SetCurrentUiEffectActive(model, 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 id or not effectPath then
return
end
if not actionId then
model.UiDefaultId = id
end
self:PlayCharacterUiEffect(model, id, rootName, effectPath)
end
--==============================--
--desc: (外部接口)加载时装展示Ui角色动作特效
--@characterId: 角色id
--@fashionId: 时装Id
--==============================--
function XUiPanelRoleModel:LoadResCharacterUiEffect(characterId, fashionId)
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, 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: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, false)
local fashionId = XDataCenter.CharacterManager.GetShowFashionId(model.CharacterId)
local _, rootName, effectPath = XCharacterUiEffectConfig.GetEffectInfo(model.CharacterId, fashionId)
self:PlayCharacterUiEffect(model, model.UiDefaultId, rootName, effectPath)
end
--==============================--
--desc: 播放Ui角色动作特效
--==============================--
function XUiPanelRoleModel:PlayCharacterUiEffect(model, id, rootName, effectPath)
self:GetModelUiEffect(model, id, rootName, effectPath)
self:SetCurrentUiEffectActive(model, true)
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 = {}
local uiEffectArray = model.UiEffect
for i = 1, #effectPathArray do
local rootName = rootNameArray[i]
local effectPath = effectPathArray[i]
local uiEffect = self:CreateUiEffect(model, id, rootName, effectPath)
uiEffectArray[#uiEffectArray + 1] = uiEffect
end
return uiEffectArray
end
--==============================--
--desc: 生成Ui角色动作特效
--==============================--
function XUiPanelRoleModel:CreateUiEffect(model, id, rootName, effectPath)
local parent -- 搜挂点
if not rootName then
parent = model.Model.gameObject
else
parent = model.Model.gameObject:FindGameObject(rootName)
if not parent then
parent = model.Model.gameObject
end
end
local fx = parent:LoadPrefab(effectPath, false)
return fx
end
function XUiPanelRoleModel:SetCurrentUiEffectActive(model, isActive)
if model.UiEffect then
for i = 1, #model.UiEffect do
model.UiEffect[i].gameObject:SetActiveEx(isActive)
end
end
end
--endregion------------------------------------加载Ui角色动作特效end---------------------------
--==============================--
--desc: 更新角色模型
--@characterId: 角色id
--@targetPanelRole: 目标面板
--@targetUiName: 目标ui名
--==============================--
function XUiPanelRoleModel:UpdateCharacterModel(
characterId,
targetPanelRole,
targetUiName,
cb,
weaponCb,
fashionId,
growUpLevel,
hideEffect,
isShowDefaultWeapon,
isNotSelf)
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)
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, hideEffect, nil, weaponFashionId, isShowDefaultWeapon) --- todo cur equip
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
)
self:LoadCharacterUiEffect(tonumber(characterId), nil, isNotSelf)
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)
end
function XUiPanelRoleModel:LoadCharacterUiEffectOther(character, actionId)
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, 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 id or not effectPath then
return
end
if not actionId then
model.UiDefaultId = id
end
self:PlayCharacterUiEffect(model, id, rootName, effectPath)
end
--==============================--
--desc: 更新机器人角色模型
--==============================--
function XUiPanelRoleModel:UpdateRobotModel(robotId, 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
local weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
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)
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
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)
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: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)
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
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)
local char = fightNpcData.Character
if char then
local modelName
local fashionId = char.FashionId
local needDisplayController
if isCute then
modelName = XFubenSpecialTrainConfig.GetCuteModelModelName(char.Id)
needDisplayController = true
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: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
self:LoadResCharacterUiEffect(char.Id, fashionId)
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)
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
XModelManager.LoadRoleWeaponModel(
roleModel.Model,
equipModelIdList,
self.RefName,
weaponCb,
hideEffect,
self.GameObject,
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
)
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 int 状态机层级
---=================================================
function XUiPanelRoleModel:PlayAnima(AnimaName, fromBegin, callBack, errorCb, layer)
local animatorlaye = layer or 0
local IsCanPlay, animator = self:CheckAnimaCanPlay(AnimaName)
if IsCanPlay and animator then
if fromBegin then
animator:Play(AnimaName, animatorlaye, 0)
else
animator:Play(AnimaName, animatorlaye)
end
if callBack then
XScheduleManager.ScheduleOnce(
function()
AddPlayingAnimCallBack(self, animator, AnimaName, callBack, animatorlaye)
end,
1
)
end
else
if errorCb then
errorCb()
end
end
return IsCanPlay
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)
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 oriAnima == nil or (clip and clip.name == oriAnima) then
-- 停止UI特效
local model = self.RoleModelPool[self.CurRoleName]
self:SetCurrentUiEffectActive(model, false)
animator:Play(clip.name, 0, 0.999)
end
end
function XUiPanelRoleModel:GetAnimator()
if self.RoleModelPool[self.CurRoleName] then
return self.RoleModelPool[self.CurRoleName].Model:GetComponent("Animator")
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
--==============================--
--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 rootName, fxPath
if showDefaultFx then
--通过解放等级获取默认解放特效配置
rootName, fxPath = XDataCenter.CharacterManager.GetCharLiberationLevelEffectRootAndPath(characterId, growUpLevel)
else
--通过角色Id获取时装对应解放特效配置
rootName, fxPath = XDataCenter.CharacterManager.GetCharFashionLiberationEffectRootAndPath(characterId, growUpLevel, fashionId)
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)
else
liberationFx:SetActiveEx(true)
end
end
---=================================================
--- 材质控制器相关特效需要跟模型绑定
---@param effect GameObject
---=================================================
function XUiPanelRoleModel:BindEffect(effect)
XLog.Debug("bind effect " .. self.CurRoleName)
if self.CurRoleName and self.RoleModelPool[self.CurRoleName] and self.RoleModelPool[self.CurRoleName].RenderingProxy then
self.RoleModelPool[self.CurRoleName].RenderingProxy:BindEffect(effect)
end
end
---=================================================
--- 设置LoadEffect接口最大加载特效数量默认最大是1
---=================================================
function XUiPanelRoleModel:SetEffectMaxCount(value)
self.EffectMaxCount = value
end
---=================================================
--- 加载特效可支持多次加载特效需要提前设置EffectMaxCount
---@param effectPath 特效路径
---@param isBindEffect 材质控制器相关特效和模型绑定
---=================================================
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
---=================================================
---生成指定名称的父节点并在其下加载特效
---@param effectPath 特效路径
---@param effectParentName 生成一个前缀Customize_+ effectParentName的节点特效将挂载在其下。不指定时默认生成一个Default_EffectParent节点供挂载
---@param isBindEffect 材质控制器相关特效和模型绑定
---@param isDisableOldEffect 为true时UnActive指定节点名下挂载的特效
---@param isUseModelParent 为true时该特效节点挂载在模型下
---=================================================
local CreateEffectParentName = function(name)
return name and string.format("Customize_%s", name) or "Default_EffectParent"
end
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: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
end
--==============================--
--desc: 更新Q版角色模型 参数都是复制自UpdateRobotModel
--==============================--
function XUiPanelRoleModel:UpdateCuteModel(robotId, characterId, weaponCb, fashionId, equipTemplateId, modelCb, needDisplayController
, targetPanelRole, targetUiName)
local modelName = XFubenSpecialTrainConfig.GetCuteModelModelName(characterId)
if not modelName then
return
end
self:UpdateRoleModel(
modelName,
targetPanelRole,
targetUiName,
function(model)
if not self.HideWeapon then
local weaponFashionId = XRobotManager.GetRobotWeaponFashionId(robotId)
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:LoadResCharacterUiEffect(characterId, fashionId)
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
return XUiPanelRoleModel