PGRData/Script/matrix/xui/xuimovie/XUiGridMovieSpineActor.lua

307 lines
10 KiB
Lua
Raw Normal View History

2024-09-01 20:49:41 +00:00
local XUiGridMovieSpineActor = XClass(nil, "XUiGridMovieSpineActor")
local DEFAULT_KOU_SPEED = 1
local ROLE_ANIM_TIME = 4
local ROLE_ANIM2_TIME = 1
local DEFAULT_GRAY_SCALE = 0 -- 默认灰度值
local DEFAULT_COLOR = CS.UnityEngine.Color.white
local BLACK_COLOR = CS.UnityEngine.Color(0.39, 0.39, 0.39, 1)
function XUiGridMovieSpineActor:Ctor(uiRoot, obj, actorIndex)
self.UiRoot = uiRoot
self.GameObject = obj.gameObject
self.Transform = obj.transform
self.ActorIndex = actorIndex
self.ActorId = nil -- 角色id
self.AnimIndex = 0 -- 角色动画的下标
self.TransIndex = 0 -- 转换动画的下标
self.TalkSpeed = 1 -- 讲话的速度
self.IsTalking = false -- 是否在讲话状态
self.GrayValue = 0 -- 灰度值
XTool.InitUiObject(self)
self.GameObject.gameObject:SetActiveEx(false)
end
function XUiGridMovieSpineActor:Destroy()
self.UiRoot = nil
end
function XUiGridMovieSpineActor:UpdateSpineActor(actorId, animIndex)
if self.ActorId == actorId then
self.AnimIndex = animIndex
-- 播放动画
self:PlayAnimationsLoop(self.AnimIndex)
self:UpdateKouAnim()
-- 更新灰度值
self:UpdateGrayScale(true)
else
self.ActorId = actorId
self.AnimIndex = animIndex
self:LoadSpine()
end
end
function XUiGridMovieSpineActor:LoadSpine()
self.SpinePath = XMovieConfigs.GetSpineActorSpinePath(self.ActorId)
if not string.IsNilOrEmpty(self.SpinePath) then
self:StopAnimationsLoop()
local spine = self.SpineLink:LoadPrefab(self.SpinePath)
self.SpineUiObject = spine:GetComponent("UiObject")
-- 加载完直接播配置的动画
self:PlayAnimationsLoop(self.AnimIndex)
self:UpdateKouAnim()
-- 更新灰度值
self:UpdateGrayScale(true)
end
end
function XUiGridMovieSpineActor:SetPos(pos)
if self.Pos == pos then return end
self.Pos = pos
self.SpineLink.anchoredPosition3D = pos
end
function XUiGridMovieSpineActor:GetPos()
return self.Pos
end
function XUiGridMovieSpineActor:SetShow(isShow)
self.GameObject.gameObject:SetActiveEx(isShow)
end
function XUiGridMovieSpineActor:IsShow()
return self.GameObject.gameObject.activeSelf
end
-- 播放讲话动画
function XUiGridMovieSpineActor:PlayKouTalkAnim(speed)
self.IsTalking = true
self.TalkSpeed = speed
local kouComponent = self.SpineUiObject:GetObject("Kou")
local talkAnim = XMovieConfigs.GetSpineActorKouTalkAnim(self.ActorId, self.AnimIndex)
if kouComponent and talkAnim and kouComponent.AnimationState then
local curAnimName = kouComponent.AnimationState:ToString()
if talkAnim and talkAnim ~= curAnimName then
kouComponent.AnimationState:SetAnimation(0, talkAnim, true)
kouComponent.timeScale = speed == 0 and DEFAULT_KOU_SPEED or speed / 1000
end
end
end
-- 播放待机动画
function XUiGridMovieSpineActor:PlayKouIdleAnim()
self.IsTalking = false
local kouComponent = self.SpineUiObject:GetObject("Kou")
local idleAnim = XMovieConfigs.GetSpineActorKouIdleAnim(self.ActorId, self.AnimIndex)
if kouComponent and idleAnim and kouComponent.AnimationState then
local curAnimName = kouComponent.AnimationState:ToString()
if idleAnim and idleAnim ~= curAnimName then
kouComponent.AnimationState:SetAnimation(0, idleAnim, true)
kouComponent.timeScale = DEFAULT_KOU_SPEED
end
end
end
-- 更新当前口的动画
function XUiGridMovieSpineActor:UpdateKouAnim()
if self.IsTalking then
self:PlayKouTalkAnim(self.TalkSpeed)
else
self:PlayKouIdleAnim()
end
end
-- 播放ui动画
-- isOnce为只播一次再次触发时则跳过不播
function XUiGridMovieSpineActor:PlayUiAnimation(animName, finishCb, isOnce)
if not self.SpineUiObject or not self:IsShow() then
return
end
if isOnce then
if self.LastUiAnimation == animName then
return
end
-- PanelActorEnable与PanelActorDarkDisable效果相似
if self.LastUiAnimation == XMovieConfigs.SpineActorAnim.PanelActorEnable and
animName == XMovieConfigs.SpineActorAnim.PanelActorDarkDisable then
return
end
end
self.LastUiAnimation = animName
local anim = self.SpineUiObject:GetObject(animName)
if anim then
anim.gameObject:PlayTimelineAnimation(finishCb)
elseif finishCb then
finishCb()
end
end
-- 播放spine角色动画
function XUiGridMovieSpineActor:PlayAnim(animIndex, transIndex)
self.AnimIndex = animIndex
self.TransIndex = transIndex
local roleComponent = self.SpineUiObject:GetObject("Role") -- Spine.Unity.SkeletonGraphic
if roleComponent then
self:StopAnimationsLoop()
-- 当前动画播完回调
self.CurCompleteCb = function()
local transAnimName = transIndex == 0 and nil or XMovieConfigs.GetSpineActorTransitionAnim(self.ActorId, transIndex)
if transAnimName then
roleComponent.AnimationState:SetAnimation(0, transAnimName, false)
-- 过渡动画播完回调
self.TransCompleteCb = function()
self:PlayAnimationsLoop(animIndex)
self:UpdateKouAnim()
roleComponent.AnimationState:Complete('-', self.TransCompleteCb)
end
roleComponent.AnimationState:Complete('+', self.TransCompleteCb)
else
self:PlayAnimationsLoop(animIndex)
self:UpdateKouAnim()
end
roleComponent.AnimationState:Complete('-', self.CurCompleteCb)
end
roleComponent.AnimationState:Complete('+', self.CurCompleteCb)
end
end
-- 播放两个动画组成的循环动画
function XUiGridMovieSpineActor:PlayAnimationsLoop(animIndex)
self:StopAnimationsLoop()
local roleComponent = self.SpineUiObject:GetObject("Role") -- Spine.Unity.SkeletonGraphic
local animName = XMovieConfigs.GetSpineActorRoleAnim(self.ActorId, animIndex)
local anim2Name = XMovieConfigs.GetSpineActorRoleAnim2(self.ActorId, animIndex)
if not anim2Name then
roleComponent.AnimationState:SetAnimation(0, animName, true)
else
self.PlayRoleAnim = function()
self.RoleAnimPlayTime = 0
roleComponent.AnimationState:SetAnimation(0, animName, true)
roleComponent.AnimationState:Complete('+', self.OnPlayRoleAnimComplete)
end
self.OnPlayRoleAnimComplete = function()
self.RoleAnimPlayTime = self.RoleAnimPlayTime + 1
if self.RoleAnimPlayTime == ROLE_ANIM_TIME then
self:PlayRoleAnim2()
roleComponent.AnimationState:Complete('-', self.OnPlayRoleAnimComplete)
self.RoleAnimPlayTime = 0
end
end
self.PlayRoleAnim2 = function()
self.RoleAnimPlayTime2 = 0
roleComponent.AnimationState:SetAnimation(0, anim2Name, true)
roleComponent.AnimationState:Complete('+', self.OnPlayRoleAnim2Complete)
end
self.OnPlayRoleAnim2Complete = function()
self.RoleAnimPlayTime2 = self.RoleAnimPlayTime2 + 1
if self.RoleAnimPlayTime2 == ROLE_ANIM2_TIME then
self:PlayRoleAnim()
roleComponent.AnimationState:Complete('-', self.OnPlayRoleAnim2Complete)
self.RoleAnimPlayTime2 = 0
end
end
self.PlayRoleAnim()
end
end
-- 停止动画的循环播放回调
function XUiGridMovieSpineActor:StopAnimationsLoop()
if not self.SpineUiObject then
return
end
local roleComponent = self.SpineUiObject:GetObject("Role") -- Spine.Unity.SkeletonGraphic
if self.RoleAnimPlayTime then
roleComponent.AnimationState:Complete('-', self.OnPlayRoleAnimComplete)
end
if self.RoleAnimPlayTime2 then
roleComponent.AnimationState:Complete('-', self.OnPlayRoleAnim2Complete)
end
end
-- 设置灰度值
function XUiGridMovieSpineActor:SetGrayScale(value)
if self.GrayValue == value then return end
self.GrayValue = value
self:UpdateGrayScale()
end
-- 更新灰度值
-- ignoreDefault忽略默认灰度值
function XUiGridMovieSpineActor:UpdateGrayScale(ignoreDefault)
if not self:IsShow() then return end
if not self.SpineUiObject then return end
if ignoreDefault and self.GrayValue == DEFAULT_GRAY_SCALE then return end
local kou = self.SpineUiObject:GetObject("Kou")
if kou then
local matController = kou.gameObject:GetComponent("XUiMaterialController")
if not matController then
matController = kou.gameObject:AddComponent(typeof(CS.XUiMaterialController))
end
matController:SetGrayScale(self.GrayValue)
end
local role = self.SpineUiObject:GetObject("Role")
if role then
local matController = role.gameObject:GetComponent("XUiMaterialController")
if not matController then
matController = role.gameObject:AddComponent(typeof(CS.XUiMaterialController))
end
matController:SetGrayScale(self.GrayValue)
end
end
-- 播放spine变亮动画skipAnim为true时直接设置最终的颜色不播动画
function XUiGridMovieSpineActor:PlayAnimFront(skipAnim)
if not self:IsShow() then return end
if not self.SpineUiObject then return end
local role = self.SpineUiObject:GetObject("Role")
local kou = self.SpineUiObject:GetObject("Kou")
if skipAnim then
role.color = DEFAULT_COLOR
kou.color = DEFAULT_COLOR
self.LastUiAnimation = XMovieConfigs.SpineActorAnim.PanelActorDarkDisable
else
self:PlayUiAnimation(XMovieConfigs.SpineActorAnim.PanelActorDarkDisable, nil, true)
end
end
-- 播放spine变暗动画skipAnim为true时直接设置最终的颜色不播动画
function XUiGridMovieSpineActor:PlayAnimBack(skipAnim)
if not self:IsShow() then return end
if not self.SpineUiObject then return end
local role = self.SpineUiObject:GetObject("Role")
local kou = self.SpineUiObject:GetObject("Kou")
if skipAnim then
role.color = BLACK_COLOR
kou.color = BLACK_COLOR
self.LastUiAnimation = XMovieConfigs.SpineActorAnim.PanelActorDarkNor
else
self:PlayUiAnimation(XMovieConfigs.SpineActorAnim.PanelActorDarkNor, nil, true)
end
end
return XUiGridMovieSpineActor