PGRData/Script/matrix/xentity/xsignboard/XSignBoardCamAnim.lua

350 lines
12 KiB
Lua
Raw Normal View History

2024-09-01 20:49:41 +00:00
local XSignBoardCamAnim = XClass(nil, "XSignBoardCamAnim")
function XSignBoardCamAnim:Ctor()
self:_Init()
end
function XSignBoardCamAnim:Exist()
return self.AnimPlayer and self.AnimPlayer:Exist()
end
function XSignBoardCamAnim:UpdateData(sceneId, signBoardId, ui)
self.SceneId = sceneId
self.SignBoardId = signBoardId
self.UiRoot = ui
end
function XSignBoardCamAnim:UpdateAnim(uiNode, farCam, nearCam)
local sceneRotationType = XPhotographConfigs.GetBackgroundSceneRotation(self.SceneId) or XPhotographConfigs.SceneRotationType.None
self:_InitNode(uiNode)
self:_SetSceneRotation(sceneRotationType)
self:_InitCam(farCam, nearCam)
self:_InitEffect()
self:_InitUiAnim()
end
-- 卸载动画
function XSignBoardCamAnim:UnloadAnim()
if self.AnimPlayer and self.AnimPlayer:Exist() then
XUiHelper.Destroy(self.AnimPlayer.gameObject)
end
self:_Init()
end
function XSignBoardCamAnim:Play()
self:_ResetSceneAnim()
self:_ResetPlayingUiAnim()
if self:Exist() then
self.FarCamRoot.gameObject:SetActiveEx(true)
self.NearCamRoot.gameObject:SetActiveEx(true)
self.AnimPlayer:Play() -- 播放镜头动画
self:_SetEffectAnim(1) -- 播放镜头动画上的特效
self:OnScenePlayStart() -- 播放Ui动画(如果有)
self.IsPlaying = true
end
end
function XSignBoardCamAnim:Pause()
if self:Exist() then
self.AnimPlayer:Pause() -- 暂停镜头动画
self:_SetEffectAnim(0) -- 暂停镜头动画上的特效
if self.CurPlayingUiAnim then -- 暂停Ui动画(如果Ui动画还在继续)
self.CurPlayingUiAnim:Pause()
end
end
end
function XSignBoardCamAnim:Resume()
if self:Exist() then
if not self:IsFinish() then
self.AnimPlayer:Play() -- 继续播放镜头动画(若动画已完成则不继续)
end
self:_SetEffectAnim(1) -- 继续播放镜头动画上的特效
if self.CurPlayingUiAnim and self.CurPlayingUiAnim.time < self.CurPlayingUiAnim.duration then
self.CurPlayingUiAnim:Play()-- 继续播放Ui动画(若动画已完成则不继续)
end
end
end
function XSignBoardCamAnim:Close()
self:_ResetPlayingUiAnim()
if self:Exist() then
self.FarCamRoot.gameObject:SetActiveEx(false)
self.NearCamRoot.gameObject:SetActiveEx(false)
if self.IsPlaying then
self:OnScenePlayStop() -- 播放Ui恢复动画
end
self.AnimPlayer.time = self.AnimPlayer.duration
self.IsPlaying = false
end
end
function XSignBoardCamAnim:IsFinish()
if self:Exist() then
return self.AnimPlayer.time >= self.AnimPlayer.duration
end
return true
end
function XSignBoardCamAnim:CheckIsSameAnim(sceneId, signBoardId, rootNode)
return
self:Exist() and
sceneId == self.SceneId and
self.SignBoardId == signBoardId and
self.AnimPlayer.transform.parent == rootNode
end
function XSignBoardCamAnim:GetNodeTransform()
if self.AnimPlayer then
return self.AnimPlayer.transform
end
end
function XSignBoardCamAnim:OnScenePlayStart()
if not self.UiAnimNodeRoot then
return
end
if XSignBoardConfigs.CheckIsUseSelfUiAnim(self.SignBoardId, self.UiAnimNodeRoot.name) then
self:_PlayUiAnim("UiDisable")
end
end
function XSignBoardCamAnim:OnScenePlayStop()
if not self.UiAnimNodeRoot then
return
end
if XSignBoardConfigs.CheckIsUseSelfUiAnim(self.SignBoardId, self.UiAnimNodeRoot.name) then
self:_PlayUiAnim("UiEnable")
end
end
-- private
--===============================================================================
function XSignBoardCamAnim:_Init()
self.AnimPlayer = nil -- 场景动画控制器Playable Director
self.IsPlaying = false -- 播发状态
self.FarRotation = nil -- 场景镜头旋转坐标
self.FarCamRoot = nil -- 场景镜头根节点
self.FarAnimNode = nil -- 动画实际控制的场景镜头节点
self.FarCam = nil -- 场景镜头动态挂载于FarAnimNode下
self.NearCamRoot = nil -- 角色镜头根节点
self.NearAnimNode = nil -- 角色镜头轨迹动画节点
self.NearCam = nil -- 角色镜头动态挂载于NearAnimNode下
self.EffectDic = {} -- 特效动画控制器字典
self.UiAnimNodeRoot = nil -- 预制体里用的Ui动画根节点
---@type UnityEngine.Playables.PlayableDirector[]
self.UiAnim = {} -- Ui动画字典
self.CurPlayingUiAnim = nil -- 正在播放的Ui动画
self.SceneId = nil
self.SignBoardId = nil
self.UiRoot = nil -- Ui动画控制的Ui对象根节点
end
-- SceneAnim
-------------------------------------------------------------------------------------
function XSignBoardCamAnim:_InitNode(uiNode)
self.AnimPlayer = uiNode.gameObject:GetComponent("PlayableDirector")
self:_ResetSceneAnim()
self.FarCamRoot = uiNode.transform:FindTransform("FarCamRoot")
self.FarAnimNode = self.FarCamRoot:FindTransform("AnimNode")
self.NearCamRoot = uiNode.transform:FindTransform("NearCamRoot")
self.NearAnimNode = self.NearCamRoot:FindTransform("AnimNode")
if self.SignBoardId ~= 1020305 then
self.AnimPlayer.transform.position = Vector3(0, 0, 0)
self.AnimPlayer.transform.rotation = CS.UnityEngine.Quaternion.identity
end
end
function XSignBoardCamAnim:_InitCam(farCam, nearCam)
-- v2.3 支持self.FarAnimNode和self.NearAnimNode使用Cam的position和rotation
local isUseCamPosAndRot = XSignBoardConfigs.CheckIsUseCamPosAndRot(self.SignBoardId)
--同步Far镜头相对空间位置 Far镜头可能是场景本身的
self.FarCamRoot.position = farCam.transform.position
self.FarCamRoot.rotation = farCam.transform.rotation
self.FarRotation = self.FarCamRoot.rotation
if not self.FarCam then
self.FarCam = XUiHelper.Instantiate(farCam, self.FarAnimNode)
self.FarCam.transform.position = farCam.transform.position
self.FarCam.transform.rotation = farCam.transform.rotation
if isUseCamPosAndRot then
self.FarCamRoot.transform.position = self.FarCam.transform.position
self.FarCamRoot.transform.rotation = self.FarCam.transform.rotation
self.FarCam.transform.localPosition = Vector3(0, 0, 0)
self.FarCam.transform.localRotation = CS.UnityEngine.Quaternion.identity
end
-- 关闭陀螺仪摇晃控件
local farGyroController = self.FarCam.transform:GetComponent("XCameraGyroController")
if farGyroController then
farGyroController.enabled = false
end
end
-- v2.1比安卡深痕镜头动画坐标临时调整,待后续版本修正
-- 特殊处理是因为阿尔法的镜头动画坐标基准不一样
if self.SignBoardId ~= 1020305 then
self.NearCamRoot.position = self.AnimPlayer.transform.position
self.NearCamRoot.rotation = self.AnimPlayer.transform.rotation
end
if not self.NearCam then
self.NearCam = XUiHelper.Instantiate(nearCam, self.NearAnimNode)
self.NearCam.transform.position = nearCam.transform.position
self.NearCam.transform.rotation = nearCam.transform.rotation
if isUseCamPosAndRot then
self.NearCamRoot.transform.position = self.NearCam.transform.position
self.NearCamRoot.transform.rotation = self.NearCam.transform.rotation
self.NearCam.transform.localPosition = Vector3(0, 0, 0)
self.NearCam.transform.localRotation = CS.UnityEngine.Quaternion.identity
end
local nearGyroController = self.NearCam.transform:GetComponent("XCameraGyroController")
if nearGyroController then
nearGyroController.enabled = false
end
end
end
-- 因为Ui中具有两个相机参考系如果两者方向相反则需要旋转方向使动画运动轨迹效果保持一致
-- sceneRotation:旋转类型 XPhotographConfigs.SceneRotationType
function XSignBoardCamAnim:_SetSceneRotation(sceneRotation)
if self.FarCam or not self.FarCamRoot then
return
end
if sceneRotation == XPhotographConfigs.SceneRotationType.None then
return
elseif sceneRotation == XPhotographConfigs.SceneRotationType.YRotation then
self.FarCamRoot.transform:Rotate(0, 180, 0)
end
end
-- 重置动画进度
function XSignBoardCamAnim:_ResetSceneAnim()
if self:Exist() then
self.AnimPlayer.gameObject:SetActiveEx(true)
self.AnimPlayer.time = 0
self.AnimPlayer:Evaluate()
end
end
-------------------------------------------------------------------------------------
-- SceneAnimEffect
-------------------------------------------------------------------------------------
function XSignBoardCamAnim:_InitEffect()
-- NearEffect
for i = 0, self.NearAnimNode.childCount - 1, 1 do
local effectTransform = self.NearAnimNode:GetChild(i)
local effect = effectTransform:GetComponent("XUiEffectLayer")
if not XTool.UObjIsNil(effect) then
self.EffectDic[effectTransform.gameObject.name] = effectTransform
effectTransform.transform.position = self.AnimPlayer.transform.parent.position
effectTransform.transform.rotation = self.AnimPlayer.transform.parent.rotation
end
end
-- FarEffect
for i = 0, self.FarAnimNode.childCount - 1, 1 do
local effectTransform = self.FarAnimNode:GetChild(i)
local effect = effectTransform:GetComponent("XUiEffectLayer")
if not XTool.UObjIsNil(effect) then
self.EffectDic[effectTransform.gameObject.name] = effectTransform
effectTransform.transform.position = self.AnimPlayer.transform.parent.position
effectTransform.transform.rotation = self.AnimPlayer.transform.parent.rotation
end
end
end
function XSignBoardCamAnim:_SetEffectAnim(speed)
local animater
for _, effect in pairs(self.EffectDic) do
animater = effect.childCount > 0 and effect:GetChild(0):GetComponent("Animator") or nil
if not XTool.UObjIsNil(animater) then
animater.speed = speed
end
end
end
-------------------------------------------------------------------------------------
-- UiAnim
-------------------------------------------------------------------------------------
function XSignBoardCamAnim:_InitUiAnim()
local uiAnimRoot = self.AnimPlayer.transform:FindTransform("Animation")
if not self.UiRoot or not uiAnimRoot then
return
end
self.UiAnimNodeRoot = uiAnimRoot:FindTransform(self.UiRoot.Name)
if not self.UiAnimNodeRoot then
return
end
for i = 0, self.UiAnimNodeRoot.childCount - 1, 1 do
local anim = self.UiAnimNodeRoot:GetChild(i)
local playableDirector = anim:GetComponent("PlayableDirector")
if not playableDirector then
goto CONTINUE
end
local tracks = playableDirector.playableAsset:GetOutputTracks()
for i = 0, tracks.Length - 1, 1 do
playableDirector:SetGenericBinding(tracks[i], self.UiRoot.GameObject:GetComponent("Animator"))
end
self.UiAnim[anim.name] = playableDirector
self.UiAnim[anim.name].gameObject:SetActiveEx(false)
:: CONTINUE ::
end
end
function XSignBoardCamAnim:_PlayUiAnim(animName, cbFunc)
if not self.UiAnim[animName] then
if cbFunc then
cbFunc()
end
return
end
self.CurPlayingUiAnim = self.UiAnim[animName]
self.UiAnim[animName].gameObject:SetActiveEx(true)
self.UiAnim[animName].gameObject:PlayTimelineAnimation(function ()
self.CurPlayingUiAnim = nil
if cbFunc then
cbFunc()
end
end)
end
-- 停止所有动画
function XSignBoardCamAnim:_ResetPlayingUiAnim()
if not self:Exist() then
return
end
if self.CurPlayingUiAnim == nil then
return
end
self.CurPlayingUiAnim:Evaluate()
self.CurPlayingUiAnim.gameObject:SetActiveEx(false)
self.CurPlayingUiAnim = nil
end
-------------------------------------------------------------------------------------
--===============================================================================
return XSignBoardCamAnim