效果(动画不流畅是gif帧率低造成的)
入口代码
Assets/FruitMachine/FruitMachineDemo.cs
这个脚本挂在Layer节点上
public class FruitMachineDemo : MonoBehaviour {private LuaEnv m_LuaEnv;private RectTransform m_Layer;private List<Action> m_Actions = new List<Action>();void Awake(){m_Layer = (RectTransform)transform;}void Start(){m_LuaEnv = new LuaEnv();m_LuaEnv.AddLoader((ref string filePath) =>{filePath = filePath.Replace('.', '/');var assetFilePath = $"Assets/{filePath}.lua.txt"; #if UNITY_EDITORfilePath = Path.GetFullPath(assetFilePath); #endifvar txtAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(assetFilePath);return Encoding.UTF8.GetBytes(txtAsset.text);});m_LuaEnv.Global.Set("FruitMachineDemoInst", this); //在lua中增加一个全局变量,可以在lua中用FruitMachineDemoInst来访问c#对象m_LuaEnv.DoString("require('FruitMachine.Main')");}void OnDestroy(){m_Actions.Clear();m_Actions = null;if (null != m_LuaEnv){m_LuaEnv.Dispose();m_LuaEnv = null;}}public RectTransform GetLayerRoot(){return m_Layer;}public void AddAction(Action action){if (null != action)m_Actions.Add(action);}public void RemoveAction(Action action){if (null != action)m_Actions.Remove(action);}void Update(){if (m_Actions.Count > 0){foreach (var act in m_Actions){act();}}}}
Assets/FruitMachine/Main.lua.txt
require("Lua.LuaCoMgr") local Type_Button = typeof(CS.UnityEngine.UI.Button)---@type FruitMachineAnim local m_FruitMachineAnim = require("FruitMachine.FruitMachineAnim").new()-- //////////local Inner = {}local m_RootTrans = FruitMachineDemoInst:GetLayerRoot()local m_ItemUIs = {} local m_CurItemIndex = 1local m_BlinkCoId = 0-- //////////m_RootTrans:Find("btn_Start"):GetComponent(Type_Button).onClick:AddListener(function()if 0 == m_BlinkCoId thenm_FruitMachineAnim:StartForResult(5)end end)for i=1,8 dolocal itemTrans = m_RootTrans:Find("item_"..i)m_ItemUIs[i] = {selFrame = itemTrans:Find("selFrame").gameObject,} endm_FruitMachineAnim:Prepare(8, function(flag, sender)local oldItemIndex = m_CurItemIndexm_CurItemIndex = m_FruitMachineAnim:GetCurIndex() m_ItemUIs[oldItemIndex].selFrame:SetActive(false)m_ItemUIs[m_CurItemIndex].selFrame:SetActive(true)if "ItemChange" == flag thenelseif "ShowResult" == flag thenm_BlinkCoId = LuaCoMgr.Start(function()for i=1,3 doLuaCoMgr.WaitForSeconds(0.1)m_ItemUIs[m_CurItemIndex].selFrame:SetActive(false)LuaCoMgr.WaitForSeconds(0.1)m_ItemUIs[m_CurItemIndex].selFrame:SetActive(true)endLuaCoMgr.WaitForSeconds(1)m_BlinkCoId = 0m_FruitMachineAnim:StartForIdle()end)end end) m_FruitMachineAnim:StartForIdle()function Inner.Update()LuaCoMgr.OnUpdate()m_FruitMachineAnim:OnUpdate() endFruitMachineDemoInst:AddAction(Inner.Update)
LuaCoMgr看这边:xlua - lua协程模拟Unity协程
动画代码
Assets/FruitMachine/FruitMachineAnim.lua.txt
local _Time = CS.UnityEngine.Time---@class FruitMachineAnim local FruitMachineAnim = {} FruitMachineAnim.__index = FruitMachineAnimlocal Inner = {}function FruitMachineAnim.new()local obj = {}setmetatable(obj, FruitMachineAnim)obj:ctor()return obj endfunction FruitMachineAnim:ctor()self.m_RunningFlag = 0 endfunction FruitMachineAnim:GetCurIndex()return self.m_CurIndex endfunction FruitMachineAnim:Prepare(cnt, cb)if 0 ~= self.m_RunningFlag then--要在运行前调用returnendself.m_Cnt = cntself.m_Callback = cbself.m_ElapseTime = 0self.m_CurIndex = 0 endfunction FruitMachineAnim:StartForIdle()if 0 ~= self.m_RunningFlag then--播放动画中returnendself.m_RunningFlag = 1self.m_ResultIndex = -1self.m_ItemChangeInterval = 0.7 endfunction FruitMachineAnim:StartForResult(resultIndex)if 2 == self.m_RunningFlag then--播放抽奖动画中returnendself.m_RunningFlag = 2self.m_ResultIndex = resultIndexself.m_ShowResultFlag = falseLuaCoMgr.Start(Inner.DoSpeedUpAndDown, self) endfunction FruitMachineAnim:StopForIdle()if 2 == self.m_RunningFlag then--播放抽奖动画中, 不能强制停止returnendself.m_RunningFlag = 0 endfunction FruitMachineAnim:IsPlayIdle()return 1 == self.m_RunningFlag endfunction FruitMachineAnim:IsPlayResult()return 2 == self.m_RunningFlag end---@param self FruitMachineAnim function Inner.DoSpeedUpAndDown(self)self.m_ItemChangeInterval = 0.7-- ///// 加速local initInterval = 0.7 --初始切换间隔local speedUpInterval = 0.03 --加速到最快时的切换间隔local speedUpCnt = 10 -- 加速次数local speedUpTotalTime = 0.5 --加速总共用时local speedUpStep = (initInterval - speedUpInterval) / speedUpCntlocal speedUpPerTime = speedUpTotalTime / speedUpCntfor i=1,speedUpCnt doLuaCoMgr.WaitForSeconds(speedUpPerTime)self.m_ItemChangeInterval = self.m_ItemChangeInterval - speedUpStependlocal speedUpDur = 2 --达到最快后持续时长 LuaCoMgr.WaitForSeconds(speedUpDur)-- /////-- ///// 减速local speedDownInterval = 0.2 --减速到最慢时的切换间隔local speedDownCnt = 10 --减速次数local speedDownTotalTime = 2 --减速总共用时local speedDownStep = (speedDownInterval - speedUpInterval) / speedDownCntlocal speedDownPerTime = speedDownTotalTime / speedDownCntfor i=1,speedDownCnt doLuaCoMgr.WaitForSeconds(speedDownPerTime)self.m_ItemChangeInterval = self.m_ItemChangeInterval + speedDownStependlocal speedDownDur = 0.5LuaCoMgr.WaitForSeconds(speedDownDur)-- ///// self.m_ShowResultFlag = true endfunction FruitMachineAnim:OnUpdate()if 0 == self.m_RunningFlag thenreturnendself.m_ElapseTime = self.m_ElapseTime + _Time.unscaledDeltaTimeif self.m_ElapseTime >= self.m_ItemChangeInterval thenself.m_ElapseTime = self.m_ElapseTime - self.m_ItemChangeIntervalself.m_CurIndex = self.m_CurIndex + 1if self.m_CurIndex > self.m_Cnt thenself.m_CurIndex = 1endif self.m_ShowResultFlag then --结果出来了if self.m_CurIndex == self.m_ResultIndex thenself.m_RunningFlag = 0self.m_ShowResultFlag = falseif self.m_Callback thenself.m_Callback("ShowResult", self)endelseif self.m_Callback thenself.m_Callback("ItemChange", self)endendelse --结果还没出来if self.m_Callback thenself.m_Callback("ItemChange", self)endendend endreturn FruitMachineAnim