该工具最初是为了帮助您在Unity中开发简单的休闲游戏而编写的,至少在那里它非常有用。
但是我想我将在其他项目中使用它,而不仅仅是在单元中。
并且,也许对您有用!
源链接
那么,他是干什么的呢?
想象一个情况:您编写了一个简单的休闲游戏,您需要轻按屏幕十次才能完成一个关卡,然后将其发送给老板(或被宠坏的客户)进行预览。
其次是任务:
- 让我们每1.5分钟添加一次广告吗?
- 之后,在开始的某个地方会出现一个窗口:“购买溢价以便没有广告”?
- 切,这个窗口会急剧破碎,但是在广告之后让我们把它打开,但是只有当玩家按下开始并经过两个关卡时才让它开吗?
- 并在10、20、30级别上出现“与朋友共享”窗口吗?
- 从第10层到第2层,将出现一个窗口“ Rate us!”?
- 还有更多!
即使对孩子进行了残酷的处决和无尽的阻拦,对窗口的位置进行了百分检查之后,您迟早也会遇到这样的问题:与计时器绑定的窗口可能与与关卡本身绑定的窗口重叠!
重做此操作变得越来越困难-毕竟,条件检查已经不容易解决,加上您的同事可以使用完全不可读的代码添加自己的窗口!该怎么办?
任务
仅在满足所有指定条件(时间已过去,到达所需点等)时,才在特定时刻调用窗口(例如,按下按钮)。
决断
为此,我创建了一个Condition类,这是它的主要字段:
- 计时器int setedSeconds
- 跳过int setedSkips
- List <int> checkPoints
, , . .
, , . , , , NextSkip(). = 0, ,
. - , START() — .
, StartTimer() ResetSkips(). , IsReady()
true , (value > 0), START() .
: — ( ) setedSeconds, , , !
IsReady() , START() , , .
public Condition myCondition;
void Start(){
myCondition = new Condition("");
myCondition.setedSeconds = 120; // 2
myCondition.setedSkips = 5;
myCondition.START(); //
}
//
public void FinishRound(){
myCondition.NextSkip(); // ,
if (myCondition.IsReady())
{
// , ...
myCondition.START(); // START() . , IsReady == true
}
}
, , — List <int> checkPoints. - , , , ., , - . , : , ( , ). , Sheduler , , — .
public Condition myCondition;
void Start(){
myCondition = new Condition("",new List<int> { 1, 2, 5 }); // ,
myCondition.setedSeconds = 120;
myCondition.setedSkips = 5;
myCondition.START();
}
public void FinishRound(){
myCondition.NextSkip();
if (myCondition.IsReady() || myCondition.HasCheckPoint(currentLevel)) //
{
// , ...
myCondition.START();
}
}
, , =) AutoInvoke(Action CallBack, int checkPoint = 0) , NextSkip() START() , START() .
public Condition myCondition;
void Start(){
myCondition = new Condition("",new List<int> { 1, 2, 5 });
myCondition.setedSeconds = 120;
myCondition.setedSkips = 5;
myCondition.START();
}
public void FinishRound(){
myCondition.AutoInvoke(() => Debug.Log("hello World"), currentLevel);
// currentLevel,
}
一个条件对象将帮助您快速为任何一个功能的操作提供一组必要条件!
如果您在TK中的任务比简单的调用(例如,每隔一次或一段时间后的调用)要困难一点,则诉诸该条件已经很有用,因为这是抽象性和可读性-您只需要启动它并检查其就绪性即可。
我已经在条件字段中添加了有用的单位属性,以便通过检查器轻松初始化!
最主要的是灵活性,如果突然有人提出了自己的功能而不应该与您的状况相冲突,您只需要创建一个通用计划器即可。
下一个任务
从程序的不同位置灵活地添加不同的窗口(函数调用),保持同步并避免重叠冲突!
解决方案:
现在我们进入了Sheduler的主要课程,我们的病情规划师!
最好尽早初始化此类的对象。特别是在一个单元中,最好将对象是DontDestroyOnLoad。
如果您在Sheduler内部查看,则可以看到以下字段:
- 当前检查点intcurrentheckPoint
- 所有添加条件及其行为的集合Dictionary&ltCondition,Action&gt ConditionHandlers-这样,
计划者就知道完成的条件应该扮演什么角色 - Dictionary <int,Condition> CheckPoints — Sheduler, Dictionary, , . .
- Queue <Condition> WaitingConditions ,
Sheduler存储每个条件的行为并根据此类进行工作,它是在添加条件public void Add(条件newCondition,操作回调)时设置的,其中参数具有必需的委托。该方法本身读取条件名称,如果条件名称为空或已添加,则引发异常-如果出于某种原因您需要从名为List&ltCondition&gt GetConditions(参数字符串[] conditionName)的日程表中获取条件,则需要此方法。另外,添加方法Add()立即运行添加条件的Start()。如果您运行Start(),这将非常有用哪个开发人员会忘记添加的条件,并且还要避免不断从Sheduler抛出此功能。如果您需要其他条件来启动条件,则只需像以前一样使用条件,就可以随时更改其计数器。这就是Sheduler的美丽-它处理条件准备就绪的地方以及更改条件的准备位置,并在调用其主要方法Condition Invoke(params Condition []徽章)时进行此计算。在自变量中,您可以指定一些徽章,即那些应该排他地起作用的条件,以及那些轮到的条件,但是它们没有出现在徽章列表中,那么它们将不起作用。但是,如果您不指定任何内容,那么,正如应该的那样,每个人都有权在排队高峰时致电!
请务必考虑将Sheduler NextCheckPoint()的检查点计入何处,例如,在方法,该回合的结束或开始时
,这是使用Sheduler所需的完整示例:
public Condition OfferBuyVip;
public Condition OfferToShareWithFriends;
public Condition OfferToVisitSite;
public Sheduler OfferSheduler;
public void Start(){
OfferSheduler = new Sheduler(currentLevel); //
/*
*
*/
OfferSheduler.Add(OfferBuyVip, () => Debug.Log(" VIP"));
OfferSheduler.Add(OfferToShareWithFriends, () => Debug.Log(" "));
OfferSheduler.Add(OfferToVisitSite, () => Debug.Log(" , "));
}
public void FinishRound(){
OfferSheduler.NextCheckPoint(currentLevel); // ,
OfferSheduler.Invoke(OfferBuyVip, OfferToShareWithFriends) // ,
}
public void StartRound(){
OfferSheduler.Invoke(OfferToVisitSite); //
// , , Sheduler
}
这就是我们确保条件的三个功能在不同的地方调用的方式,它们相互尊重并且不会连续抓取所有内容,而是尊重队列(例如现代的优惠券数字队列),并且用户会从终点线快速跳到游戏开始,因此不会影响提案的数量。使用Sheduler,它保持了简单性和灵活性之间的明显和谐,因为使用Sheduler和通过Add(条件newCondition,操作回调)方法传递给它的委托时,可以实现窗口之间的任何连接。
例如,当调用广告横幅时,在没有两个广告的情况下会显示不购买广告而购买Premium的报价:
void Start(){
OfferSheduler = new Sheduler(currentLevel);
callAddBanner = new Condition(" ");
callAddBanner.setedSeconds = 80; // 80
OfferBuyVip = new Condition(" VIP ");
OfferSheduler.Add(callAddBanner,
delegate()
{
Debug.Log(" ");
OfferBuyVip.setedSkips = 2; //
OfferBuyVip.START(); //
}
);
OfferSheduler.Add(OfferBuyVip,
delegate ()
{
Debug.Log(" VIP");
OfferBuyVip.setedSkips = 0; // !
//,
}
);
}
void Finish(){
OfferSheduler.NextCheckPoint(currentLevel); //
//
OfferSheduler.Invoke(); //
//
}
这样,现在每隔80秒就会触发一个无干扰的广告(毕竟,它不是在重要的回合中被调用,而是在终点线被调用),并且还会在您方便时调用要约来购买广告!最好的事情是,现在团队中的任何开发人员都可以将其提案添加到Sheduler,Sheduler将分发所有内容。