【前言】很早就开始想写博客了,奈何一没时间,二嫌麻烦,一直拖到现在~~作为游戏开发工作了一年多,我想把一些通用的小功能小工具写下来~~偏逻辑方面吧,适合给初入门的萌新看,大佬就别笑话我了哈T^T,我也还是一个小萌新啦~~
抽奖工具(Demo_Draw)
像问卷星填完之后的那个抽奖功能、王者荣耀钻石夺宝积分夺宝的抽奖系统……我之前作为真萌新做水果玛丽机时,对这个功能的做法犹豫了会儿,所以后面总结出一个小工具,可直接写在工具类里传参调用即可。
一、先简单拼一个UI模型
注:SprBg下的子物体(每一个可能抽中的奖励)排列顺序得按照抽奖时的循环顺序来。
这里设抽奖类型为“A”"B""C""D"四种,SprYes即为选中的那个的图。
再加上开始按钮和结果显示。初始化时不需要有结果显示。
二、我们来实现个小Demo
(注:我这里用的是NGUI,用习惯了UGUI的小伙伴别慌,对思路不影响啦~~)
1)首先,初始化各个模块,我们需要用到的东西。
2)接下来,我们理理思路。
抽奖需要循环播放各个奖励上的选中框,由此我们想到了for循环。但只用for循环的话无论循环多少次都看不出效果,不是for循环不对,而是因为循环时间太短,需要设定一个时间,所以需要用到协程(或者其他的计时器)。
这里要说一下,实际项目当中涉及抽奖的功能,都是事先在服务器里抽中了一个结果,我们得根据那个结果进行前端的展示,无论前端展示做得多么花里胡哨,结果都是已经定了的。这是因为,前端没有决定结果的权限!!所以,我们不能通过前端过程去决定结果,而需要根据结果去展现前端效果。
3)进入正式的实现方法了。
我们需要个协程方法,考虑到每次抽完时选中框可能不在第一个,而需求又不需要你重置到第一个时,就从当前选中的下一个开始循环,所以我们需要传一个开始的index参数。index即奖励列表中的排列序号。
再在Start()方法里加入其调用,即添加按钮点击事件。
我们再来看Rotate方法:
- 初始化每次抽奖前需重置的变量,以及拿到结果
- 每次循环选中框位置
for循环中的处理如下:
1)选中则把选中框作为奖励项的子物体,并将其本地坐标置为Vector3.Zero;
2)根据结果,随机一个该奖项展示,break即跳出循环。
(注:我这里是因为奖项排列有规律,所以提取出一个origIndex,若杂乱排序,则需要对每个项做处理)
- 抽完后显示结果,并处理需要此时拿到的变量
循环每个奖励项的时间等可自行调节。
这里的奖励结果直接用了int 0~3来替代ABCD四个项,可以设一个枚举,方便调用以下要说的工具。
三、提炼出一个工具类
顾名思义,工具类基本都是静态的,供我们直接调用。
实际上上面的方法只要有参数,都可直接进行调用,无需每次都重复写,所以我们创建一个工具类:
public static class Tool { }
新建静态方法,因我们需要用到一些游戏物体和变量,所以需要传这些参数:开始索引,结果索引,奖项列表,选中框,结果显示物体。此外,方法中还有些可变的量:每个奖励项循环间隔时间、循环次数、结果的初始化内容、结果显示内容、每个奖励项的索引等。
具体方法如下:
在按钮事件中调用,以及对startIndex的处理:
四、相关优化
比如抽奖带一些拖尾,当前抽中奖励的后面几个也有逐渐褪色的选中框之类的;又如抽中当前,前端显示在前一个停留一下后倒退为当前;再如根据抽中结果再做一些操作;加次数、音效、特效、计算得分等……
【后语】这个工具方法也许不太完善,可能由于循环间隔时间太短,而计算机程序执行代码时间出现延迟,就会产生还没判断跳出循环就已经执行了下一次循环的情况,导致抽奖结果和当前选中的结果不一致的情况。望大佬指教指教这个缺点T^T
【可能遗忘的知识点】关于Random.Range(min,max)这个方法的临界值问题:
· 当Range的参数是float时 返回一个随机浮点数,在min(包含)和max(包含)之间。(只读)
· 当Range的参数是int时 返回一个随机整数,在min(包含)和max(排除)之间。(只读)
当前项目代码后面会给地址~~