当我最初写游戏时,我常常使用标准Random()函数,而后写一堆if和else条件来我得到预期结果。若是结果不太好,我会写更多的条件进行过滤或者筛选,直到我以为游戏变得有趣。最近我发现有更好的方法。内置的Random类并无问题,问题是使用内置的Random类很难达到咱们的预期效果。dom
现实生活中,以抛硬币为例,时而会抛出连续屡次花或者字。那么若是在游戏中,可能表现为屡次连续的暴击或是硬直,尽管有时暴击和硬直的几率很低,但依旧有可能连续出现,让人感受诡异。那么为了解决相似的问题,前辈们想了不少种方法,好比说特殊值过滤等等。咱们今天介绍的是Shuffle Bag技术,可让你的随机数不那么随机,由你掌控。函数
Shuffle Bag是一项让咱们能够控制随机数分布的技术。性能
其主要原理为:动画
using System.Collections.Generic; using UnityEngine; public class ShuffleBag<T> { private List<T> data; private T currentItem; private int currentPosition = -1; private int Capacity { get { return data.Capacity; } } public int Size { get { return data.Count; } } public ShuffleBag(int initCapacity) { data = new List<T>(initCapacity); } public void Add(T item, int amount) { for (int i = 0; i < amount; i++) data.Add(item); currentPosition = Size - 1; } public T Next() { if (currentPosition < 1) { currentPosition = Size - 1; currentItem = data[0]; return currentItem; } var pos = Random.Range(0,currentPosition); currentItem = data[pos]; data[pos] = data[currentPosition]; data[currentPosition] = currentItem; currentPosition--; return currentItem; } }
在个人项目中,我但愿NPC播放受伤动画的几率为十分之一,而且我不但愿看到他偶尔连续播放受伤动画屡次,也不想长时间不播放受伤动画。设计
ShuffleBag<bool> hurtBag = new ShuffleBag<bool>(10); hurtBag.Add(false, 9); hurtBag.Add(true, 1); //当触发受伤时,调用如下逻辑 if(hurtBag.Next()) { Play(); }
附上参考的原文连接 Shuffle Bags: Making Random() Feel More Random 英文好的同窗能够直接看原文 。另外,这个原文题目有些让人疑惑,因此个人译文标题作了一些更改。blog