大家好! 我之前在这里发表过一篇关于程序化节点地图系统(CraftMap)的文章,几个朋友问我在做什么,我在评论中提到我正在完成一个抽奖/选秀奖励屏幕来连接整个 roguelike 循环。 这部分终于完成了,所以我想分享一下奖励数学是如何工作的。 在过去几个月里,我一直在工作于一个 loot/抽奖奖励引擎(CraftRewards)中,想要分享我最终采用了什么方法。 我试错了很多次,结果比我想象的要多。 最难的部分是: * 使“坏运气保护”看起来像是一个无形的橡皮带,而不是一个明显的橡皮带, * 在具有 100+ 个条目和嵌套子池的表格中保持加权滚动的速度, * 避免 GC 突发性增长,当单个拉动动画通过同一个 tween 系统动画 12 张牌时, * 将法律要求的掉落率披露烘焙到引擎中,而不是在最后期限前添加。 我最终采用了以下方法: 软怜惜作为一个权重梯度,而不是一个假滚动 我不触摸显示的掉落率,而是将一段时间内没有击中的玩家的高级权重加上一个奖励:bonus = clamp((pullsSince - softPityStart) * rampRate, 0, maxBonus)。 使用大多数抽奖游戏使用的数字(从拉动 75 开始,+5% 每拉动,限制在 +100% 内),拉动 76 几乎不会移动,而拉动 95 有双倍概率。 它永远不会感觉像是在脚本一样编写的,感觉只是运气转变了。 加权选择通过累积数组 + 二分搜索 在池子改变时建立一个累积总数数组,然后在每次滚动时进行二分搜索 — O(n) 建立,O(log n) 每次拉动。 比循环和重新滚动快得多,尤其是当表格变得大时。 所有池都被包含,零分配每次滚动 卡片、tween 实例和宝箱开启序列的贝塞尔路径数据都被池化,而不是实例化。 10 张牌的拉动在移动设备上没有任何 GC 突发性增长。 一旦数学变得坚固,我就建立了一个展示层:宝箱开启与贝塞尔卡片轨迹, Rarity 基于效果的翻转,Rare 拉动全屏冲击,和 roguelike “选秀 1-of-N” 模式。 我将整个内容打包为 CraftRewards 并在 Asset Store 上发布。 我再次赠送 3 个优惠券,和上次一样,如果你正在工作于 loot、抽奖或奖励系统中,留下一个评论,明天我会挑选 3 个。 愿意在评论中深入讨论怜惜数学、加权选择器或 tween 系统。