當我最初寫遊戲時,我常常使用標準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