特别适用于各种解谜关卡 , 成就系统,任务系统 ,的 通用事件处理
CheckPointHandler.cs随便挂在场景中的某个物体上 (单例模式,场景中只要有一个)
1) How To Use
CheckPoint Events 是一个列表,每个元素是一个组合事件,每个组合事件包含了一个条件列表和相应触发的UnityEvent。
Event Conditions是条件列表,每个元素是一个条件信息,比如上图表示aaa和bbb分别被触发3次以上和4次以上时触发该unity event: 关闭Book和TestCheckPoint
每个CheckPoint有一个id,并且有一个值记录该checkpoint被触发了多少次,
多个CheckPoint可以共用同一个id,上面介绍的组合事件中 条件的触发次数为所有相同id的checkpoint的触发次数之和。
可以选择能否由碰撞或者点击触发,Target为碰撞触发的tag条件(必须该tag的物体碰撞到才会触发)
超过最大触发次数之后,该checkpoint将不会再触发。(并不是id的触发次数上限,而是单个checkpoint的)
2) Code
CheckPoint.cs:
csharp
using UnityEngine;
[RequireComponent(typeof(Collider2D))]
public class CheckPoint : MonoBehaviour
{
public string id;
public int triggerCount; //触发了多少次
public bool isCollisionTrigger; //由碰撞事件触发
public bool isClickTrigger; //由点击事件触发
public string targetTag = "Player"; //能触发此checkpoint的tag
public int maxTriggerCount = 1; //最大触发次数
public string Trigger()
{
if(triggerCount >= maxTriggerCount) return "";
triggerCount++;
CheckPointHandler.Instance.UpdateTrigger(id, triggerCount);
return id;
}
private void OnMouseDown() {
if(isClickTrigger)
Trigger();
}
private void OnTriggerEnter2D(Collider2D other) {
if(isCollisionTrigger && other.tag == targetTag)
Trigger();
}
}
CheckPointHandler.cs
csharp
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[Serializable]
public class EventCondition
{
public string id;
public int count;
}
[Serializable]
public class CheckPointEvent{
public List<EventCondition> eventConditions;
public UnityEvent unityEvent;
}
public class CheckPointHandler : MonoSingleton<CheckPointHandler>
{
public List<CheckPointEvent> checkPointEvents; //组合事件
public static Dictionary<string, int> triggerHistory = new Dictionary<string, int>();
public void UpdateTrigger(string id, int Count)
{
triggerHistory[id] = Count;
Debug.Log( ($"[{0}]= {1}",id, Count));
CheckEvent();
}
public void CheckEvent()
{
foreach(var e in checkPointEvents)
{
bool flag = true;
foreach(var condition in e.eventConditions)
{
if(!triggerHistory.ContainsKey(condition.id) || triggerHistory[condition.id] < condition.count) //如果没触发够指定次数,不构成条件
{
flag = false;
break;
}
}
if(flag)
e.unityEvent.Invoke();
}
}
}