Unity 选择具有不同概率的项
思路
假设权重分别为3,2,5
随机一个0-10之间的数
1 | Math.random()*10 // [0,10) 区间开闭看实际情况 |
数字落在 [0,3),[3,5),[5,10) 哪个区间就对应选择谁
判断落在哪个区间可以通过依次减去区间长度后是否有余
例如随机数为7.856:
- 7.856 - 3 = 4.856 说明属于后面的区间则继续
- 4.856 - 2 = 2.856 说明依旧属于后面的区间
- 2.856 - 5 < 0 说明属于该区间
例如随机数为2.856:
- 2.856 - 3 < 0 说明属于该区间
文档
查看文档时发现文档也有提到这个,Adding Random Gameplay Elements
选择具有不同概率的项
有时需要随机选择项,但有些项比其他项被选中的几率更高。例如,NPC 在遇到玩家时可能会以几种不同的方式做出反应:
- 友好问候的几率为 50%
- 逃跑的几率为 25%
- 立即攻击的几率为 20%
- 提供金钱作为礼物的几率为 5%
可将这些不同的结果可视化为一张纸条,该纸条分成几个部分,每个部分占据纸条总长度的一个比例。占据的比例等于选择结果的概率。选择行为相当于沿着纸条的长度选择一个随机点(例如通过投掷飞镖),然后查看该点处于哪个部分。
在脚本中,纸条实际上是一个浮点数组,其中的浮点数按顺序包含项的不同概率。随机点是通过将 Random.value
乘以数组中所有浮点数的总和得到的(这些数值不需要加起来等于 1;重点是不同值的相对大小)。要找到该点”位于”哪个数组元素,首先要检查它是否小于第一个元素中的值。如果是,则第一个元素便是选中的元素。否则,从该点值中减去第一个元素的值,然后将其与第二个元素进行比较,依此类推,直到找到正确的元素。在代码中表示为以下所示的内容:
1 | function Choose(probs: float[]) { |
1 | float Choose (float[] probs) { |
请注意,最后的 return
语句是必要的,因为 Random.value
可以返回 1
的结果。在这种情况下,搜索将无法在任何地方找到随机点。将以下行
1 | if (randomPoint < probs[i]) |
…更改为”小于或等于”测试将避免额外的 return
语句,但也会允许偶尔选择某个项,即使其概率为零也是如此。
Unity 选择具有不同概率的项