PGRData/Script/matrix/xui/xuimoewar/sceneanimation/XMoeWarAnimationRole.lua

349 lines
No EOL
13 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.

local XMoeWarAnimationRole = XClass(nil, "XMoeWarAnimationRole")
local Vector3 = CS.UnityEngine.Vector3
local VForward = Vector3.forward
local CSXResourceManagerLoad = CS.XResourceManager.Load
local PLAY_END_ANIM_DISTANCE = CS.XGame.ClientConfig:GetFloat("MoeWarSceneAnimationPlayEndAnimDistance")--当镜头跟随者到达此位置后播放结束镜头动画和慢镜头动作
local PLAY_GOAL_ANIM_DISTANCE = CS.XGame.ClientConfig:GetFloat("MoeWarSceneAnimationGoalDistance")--当镜头跟随者到达此位置后播放冲线特效
local PLAY_RESTORE_ANIM_DISTANCE = CS.XGame.ClientConfig:GetFloat("MoeWarSceneAnimationRestoreDistance")--当镜头跟随者到达此位置后恢复慢镜头动作
local SLOW_DOWN_PERCENT = 0.01 * CS.XGame.ClientConfig:GetInt("MoeWarSceneAnimationSlowdownPercent")--慢动作速度百分比
local END_ANIM_TOTAL_TIME = CS.XGame.ClientConfig:GetInt("MoeWarSceneAnimationTotalTime")--整个终场动画持续时间/s
local ADD_SUPPORT_DISTANCE_POS = CS.XGame.ClientConfig:GetFloat("MoeWarSceneAnimationAddSupportDistance")--增加投票数间隔,数值越大,间隔时间越长,增加的投票数越多
local SynPlaySlowDownAnim = nil--同步播放慢动作
local SynPlayRestoreAnim = nil--同步恢复原始速度
function XMoeWarAnimationRole:Ctor(data)
self.Index = data.Index--赛道Index
self.GroupId = data.GroupId--动画组Id
self.ModelParent = data.Parent--角色模型父节点
self.UiName = data.UiName
self.Scene = data.Scene
self.SwitchCameraCb = data.SwitchCameraCb--切换相机回调
self.EndAnimCb = data.EndAnimCb--终场场景动画回调
self.GoalAnimCb = data.GoalAnimCb--冲线场景动画回调
self.Ui = data.Ui --ui节点
self.PlayerId = data.PlayerId --角色Id
self.RunwayIndex = data.RunwayIndex --场景的跑道下标
self.Match = data.Match --XMoeWarMatch
self:Init()
end
function XMoeWarAnimationRole:Dispose()
self:DestroyTimer()
for _, effectRoot in pairs(self.SceneEffectRoots) do
effectRoot.gameObject:SetActiveEx(false)
end
self.SceneEffectRoots = {}
self:ReleaseResource()
end
function XMoeWarAnimationRole:ReleaseResource()
if self.Resource then
self.Resource:Release()
self.Resource = nil
end
if self.Model then
XUiHelper.Destroy(self.Model)
self.Model = nil
end
end
function XMoeWarAnimationRole:Init()
local groupId = self.GroupId
local player = XDataCenter.MoeWarManager.GetPlayer(self.PlayerId)
local matchId = self.Match and self.Match:GetId() or XDataCenter.MoeWarManager.GetCurMatchId()
self.AnimationIds = XMoeWarConfig.GetAnimationIds(groupId)--动画节点组
self.CurrentAnimationIndex = 0--当前播放动画Index
self.CurrentModelName = nil--当前加载角色模型名称
self.Model = nil--当前加载角色模型
self.Animator = nil--动画控制器
self.FollowCameras = {}--跟随相机
self.SceneEffectRoots = {}--已加载场景特效根节点
self._IsEnd = nil--全部动画节点是否播放完毕
self._IsFocus = nil--是否是相机跟随者
self.PlaySlowDownAnim = nil--播放慢动作
self.PlayRestoreAnim = nil--恢复原始速度
self.TotalSupportCount = player and player:GetSupportCount(matchId) or 0 --拥有的总投票数
self.TotalDistance = XMoeWarConfig.GetAnimationTotalDistance(groupId) --总距离
self.OnceAddSupportCount = self.TotalSupportCount / self.TotalDistance * (ADD_SUPPORT_DISTANCE_POS + 0.5) --每次增加的投票数
self.CurSupportCount = 0 --当前票数
SynPlaySlowDownAnim = nil
SynPlayRestoreAnim = nil
self:InitUi()
local modelName = XMoeWarConfig.GetAnimationGroupInitModelName(groupId)
self:ChangeModel(modelName)
if player then
self.Head:SetRawImage(player:GetCircleHead())
end
self.RImgIcon:SetRawImage(CS.XGame.ClientConfig:GetString("MoeWarScheduleSupportIcon"))
self.TxtScore.text = self.CurSupportCount
self.TxtAddScore.text = ""
end
function XMoeWarAnimationRole:InitUi()
local rootUiTransform = self.Ui.transform
self.Head = XUiHelper.TryGetComponent(rootUiTransform, "Head1/StandIcon", "RawImage")
self.TxtScore = XUiHelper.TryGetComponent(rootUiTransform, "PanelRolePoll/TxtScore", "Text")
self.RImgIcon = XUiHelper.TryGetComponent(rootUiTransform, "PanelRolePoll/RImgIcon", "RawImage")
self.TxtAddScore = XUiHelper.TryGetComponent(rootUiTransform, "TxtAddScore", "Text")
self.TxtAddScoreEnable = XUiHelper.TryGetComponent(rootUiTransform, "Animation/TxtAddScoreEnable", "PlayableDirector")
end
--替换模型
function XMoeWarAnimationRole:ChangeModel(modelName)
if not modelName or modelName == self.CurrentModelName then return end
--记录旧模型位置
local oldPos = self.Model and self.Model.transform.localPosition
--加载新模型
local prefabPath = XModelManager.GetUiModelPath(modelName)
local resource = CSXResourceManagerLoad(prefabPath)
if resource == nil or not resource.Asset then
XLog.Error(string.format("XMoeWarAnimationRole:ChangeModel加载资源失败路径%s", prefabPath))
return
end
self:ReleaseResource()
self.Resource = resource
local model = XUiHelper.Instantiate(resource.Asset, self.ModelParent)
model.gameObject:SetLayerRecursively(CS.UnityEngine.LayerMask.NameToLayer("UiNear"))
self.Model = model
if oldPos then
self.Model.transform.localPosition = oldPos
end
--加载controller
local controllerPath = XModelManager.GetUiControllerPath(modelName)
local runtimeController = CS.LoadHelper.LoadUiController(controllerPath, self.UiName)
self.Animator = model.transform:GetComponent("Animator")
self.Animator.runtimeAnimatorController = runtimeController
--播放初始动画
local initAnim = XMoeWarConfig.GetAnimationGroupInitAnim(self.GroupId)
if not string.IsNilOrEmpty(initAnim) then
self.Animator:Play(initAnim)
end
--切换模型时换一个相机跟随保证平滑,否则会延迟回拉
if self.CurrentModelName and modelName ~= self.CurrentModelName then
self.SwitchCameraCb(self.Index)
end
self.CurrentModelName = modelName
end
--设置跟随虚拟相机
function XMoeWarAnimationRole:SetFollowCamera(virtualCamera)
if self.FollowCameras[virtualCamera] then return end
self._IsFocus = true
self.FollowCameras = {}
self.FollowCameras[virtualCamera] = virtualCamera
self:UpdateFollowCameras()
end
function XMoeWarAnimationRole:UpdateFollowCameras()
for virtualCamera in pairs(self.FollowCameras) do
virtualCamera.Follow = self.Model.transform
end
end
--执行动画节点
function XMoeWarAnimationRole:Run()
local animationIndex = self.CurrentAnimationIndex + 1
local animationId = self.AnimationIds[animationIndex]
local isLastAnimation = animationIndex >= #self.AnimationIds - 1 --最后一个动画到达终点,-1来判断是否为终点前的最后一个动画
if not XTool.IsNumberValid(animationId) then
self:OnExit()
return
end
self.CurrentAnimationIndex = animationIndex
self._IsEnd = false
--替换动画模型
local modelName = XMoeWarConfig.GetAnimationModelName(animationId)
self:ChangeModel(modelName)
--角色动作
local animName = XMoeWarConfig.GetAnimationAnimName(animationId)
self.Animator:Play(animName)
--角色特效
local roleEffect, roleEffectRoot = XMoeWarConfig.GetAnimationRoleEffect(animationId)
if not string.IsNilOrEmpty(roleEffect)
and not string.IsNilOrEmpty(roleEffectRoot)
then
local effectRoot = self.Model.transform:FindTransform(roleEffectRoot)
if XTool.UObjIsNil(effectRoot) then
XLog.Error(string.format("XMoeWarAnimationRole:Run error: 角色特效父节点找不到, roleEffectRoot: %sanimationId: %s", roleEffectRoot, animationId))
else
effectRoot:LoadPrefab(roleEffect, false)
effectRoot.gameObject:SetActiveEx(false)
effectRoot.gameObject:SetActiveEx(true)
end
end
--场景特效
local sceneEffect, sceneEffectRoot = XMoeWarConfig.GetAnimationSceneEffect(animationId, self.RunwayIndex)
if not string.IsNilOrEmpty(sceneEffect)
and not string.IsNilOrEmpty(sceneEffectRoot)
then
local effectRoot = self.SceneEffectRoots[sceneEffectRoot]
if not effectRoot then
effectRoot = self.Scene:FindTransform(sceneEffectRoot)
self.SceneEffectRoots[sceneEffectRoot] = effectRoot
end
if XTool.UObjIsNil(effectRoot) then
XLog.Error("XMoeWarAnimationRole:Run error: 场景特效父节点找不到, sceneEffectRoot: " .. sceneEffectRoot)
else
effectRoot.gameObject:SetLayerRecursively(CS.UnityEngine.LayerMask.NameToLayer("UiNear"))
effectRoot:LoadPrefab(sceneEffect, false)
effectRoot.gameObject:SetActiveEx(false)
effectRoot.gameObject:SetActiveEx(true)
end
end
--速度
local speed = XMoeWarConfig.GetAnimationSpeed(animationId)
--目标点
local distance = XMoeWarConfig.GetAnimationDistance(animationId)
local transform = self.Model.transform
local start = transform.localPosition.z
local target = start + distance
--触发动画
local playEndAnim = nil
local playGoalAnim = nil
--终点前加满至拥有的投票数
if isLastAnimation then
self:AddScore(self.TotalSupportCount)
end
--角色移动
local position = nil
local curPosition = nil
self:DestroyTimer()
self.Timer = XScheduleManager.ScheduleForever(function()
if XTool.UObjIsNil(transform) then
self:DestroyTimer()
return
end
position = transform.localPosition.z
--增加当前的投票数
if not isLastAnimation then
if not curPosition then
curPosition = position
elseif math.abs(curPosition - position) >= ADD_SUPPORT_DISTANCE_POS then
curPosition = position
self.CurSupportCount = math.min(self.TotalSupportCount, self.CurSupportCount + self.OnceAddSupportCount)
self:AddScore(self.CurSupportCount)
end
end
--到达目标位置后执行下一动画节点
if position >= target then
self:DestroyTimer()
self:Run()
return
end
--终场镜头动画
if self._IsFocus and position >= PLAY_END_ANIM_DISTANCE then
if not playEndAnim then
playEndAnim = true
--播放场景动画
self.EndAnimCb(END_ANIM_TOTAL_TIME)
end
if not SynPlaySlowDownAnim then
SynPlaySlowDownAnim = true
end
end
--慢动作
if SynPlaySlowDownAnim and not self.PlaySlowDownAnim then
self.PlaySlowDownAnim = true
speed = speed * SLOW_DOWN_PERCENT
self.Animator.speed = self.Animator.speed * SLOW_DOWN_PERCENT
end
--冲线动画
if not playGoalAnim and self._IsFocus and position >= PLAY_GOAL_ANIM_DISTANCE then
playGoalAnim = true
--播放冲线特效
self.GoalAnimCb()
end
--恢复原始速度
if self._IsFocus and not SynPlayRestoreAnim and position >= PLAY_RESTORE_ANIM_DISTANCE then
SynPlayRestoreAnim = true
end
if SynPlayRestoreAnim and not self.PlayRestoreAnim then
self.PlayRestoreAnim = true
speed = speed / SLOW_DOWN_PERCENT
self.Animator.speed = self.Animator.speed / SLOW_DOWN_PERCENT
end
--角色移动
transform:Translate(speed * VForward * CS.UnityEngine.Time.deltaTime)
end, 0, 0)
end
--增加积分动画
function XMoeWarAnimationRole:AddScore(newSupportCount)
local oldSupportCount = tonumber(self.TxtScore.text)
if oldSupportCount == newSupportCount or newSupportCount - oldSupportCount < 1 then
return
end
local curShowSupportCount = self.TxtScore.text
self.TxtScore.text = math.min(self.TotalSupportCount, math.floor(newSupportCount))
self.TxtAddScore.text = "+" .. math.floor(newSupportCount - oldSupportCount)
self.TxtAddScoreEnable:Stop()
self.TxtAddScoreEnable:Play()
end
--动画全部执行完毕
function XMoeWarAnimationRole:OnExit()
self._IsEnd = true
self:DestroyTimer()
end
function XMoeWarAnimationRole:DestroyTimer()
if self.Timer then
XScheduleManager.UnSchedule(self.Timer)
self.Timer = nil
end
end
function XMoeWarAnimationRole:IsEnd()
return self._IsEnd or false
end
return XMoeWarAnimationRole