一:目的
游戏开发中,经常会执行一连串的事件。例如在第2秒的时候播放攻击动画,在第5秒的时候播放走路动画,如果在上层类的Update中编写逻辑会增加代码冗余
所以我们需要一个事件序列类去统一管理
二:解决的问题及优点
——减少代码冗余
三:使用
——创建事件序列
s = new Sequence();
——添加事件序列
s.AddEvent(0, () =>
{
Debug.Log("event1");
});
s.AddEvent(1, () =>
{
Debug.Log("event2");
});
s.AddEvent(2, () =>
{
Debug.Log("event3");
});
——播放事件序列
s.Play();
——在每帧刷新的方法中调用Update方法
s.Update(Time.deltaTime);
四:代码实现
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 事件序列
/// </summary>
public class Sequence
{
/// <summary>
/// 事件
/// </summary>
public class Event
{
public float eventTime;//事件时间
public List<Action> eventList;//事件列表
public Event(float eventTime)
{
this.eventTime = eventTime;
eventList = new List<Action>();
}
public void Invoke()
{
foreach (var e in eventList)
{
e?.Invoke();
}
}
}
Dictionary<float, Event> eventOriginalCache = new Dictionary<float, Event>();//事件原始列表
Dictionary<float, Event> eventPlayCache = new Dictionary<float, Event>();//事件播放列表(从事件原始列表拷贝一份)
bool isPlaying;//序列是否在播放
/// <summary>
/// 播放事件序列
/// </summary>
public void Play()
{
if (isPlaying) return;
CopyEvents();
seqTimer = 0;
isPlaying = true;
}
/// <summary>
/// 添加事件
/// </summary>
public void AddEvent(float eventTime, Action customEvent)
{
if (!eventOriginalCache.ContainsKey(eventTime))
{
Event e = new Event(eventTime);
eventOriginalCache.Add(eventTime, e);
}
eventOriginalCache[eventTime].eventList.Add(customEvent);
}
float seqTimer;//序列计时器
List<float> delEventCache = new List<float>();//要删除的事件节点
public void Update(float timeDelta)
{
if (!isPlaying) return;
delEventCache.Clear();
seqTimer += timeDelta;
foreach (var temp in eventPlayCache)
{
if (seqTimer >= temp.Key)
{
Event sequenceEvent = temp.Value;
sequenceEvent.Invoke();
delEventCache.Add(temp.Key);
}
}
foreach (var eventTime in delEventCache)
{
eventPlayCache.Remove(eventTime);
}
if (eventPlayCache.Count <= 0)
{
isPlaying = false;
}
}
/// <summary>
/// 拷贝事件
/// </summary>
void CopyEvents()
{
eventPlayCache.Clear();
foreach (var temp in eventOriginalCache)
{
eventPlayCache.Add(temp.Key, temp.Value);
}
}
}