天天看點

Unity3D中随機函數的應用

電子遊戲中玩家與系統進行互動的樂趣絕大多數取決于事件發生的不可預知性和随機性。在unity3D的API中提供了Random類來解決随機問題。

最簡單的應用就是在數組中随機選擇一個元素,使用Random内置的方法可以進行選擇。代碼如下:

Floatelement=myArray[Random.Range(0,myArray.Length)];

Random.Range方法的兩個參數代表了選擇資料元素的範圍。

很多時候,遊戲中運用更複雜的随機事件,下面描述幾種常見的随機事件案例

1:随機選擇具有不同機率的事件

當你你需要選擇具有不同發生機率的事件元素時。運用的場景為在遊戲中玩家遇到NPC時,NPC在系統内部有好幾種與玩家互動的方法。但是這些方法發生的機率并不相等。例如有50%幾率進行問好;25%幾率跑開;20%幾率攻擊玩家;5%幾率為玩家提供禮品。

學過機率統計學的同學,一定做過在連續時間内發生事件機率的模型。我們也可以将上面描述的需求抽象為一個模型,我們将整個NPC與玩家互動系統看做一個紙帶,按照事件發生的機率将紙帶分為若幹段,将大機率事件排在前面,小機率事件排在後面。當玩家遇到NPC時代表在這個紙帶上随機選擇一個點。抽象結果用圖如下:

Unity3D中随機函數的應用
随機選擇的點在哪個事件範圍内就會發生相應的事件。将這個模型用代碼表示為:

float Choose(float[] Probs)
{
//将事件元素加入到數組中,如上面有4個元素,分别為50,25,20,5
    {
        float total=0;
        Foreach(float elem in probs )
        Total+=elem;
}
//Random.value方法傳回一個0—1的随機數
float randomPoint=Random.value*total;
for(int i=0;i<pros.Length;i++ )
{
    if(randomPoint<probs[i])
    return i;
    else
    randomPoint-=probs[i];
}
return probs.length-1;
    }      

過程描述:首先檢查随機數是否小于第一個元素,如果小于那麼第一個元素就被選擇了。否則用随機數的值減去第一個元素的值然後與第二個元素進行比較,以此類推直到找到正确的元素為止。

過程驗證:如上圖所示,假如随機數最終為82,那麼首先将82與第一個元素50比較:82>50,是以應該将82-50=32與第二個元素25進行比較:32>25,是以應該将32-25=7與第三個元素20進行比較:7<20,那麼第三個元素被選中,相對應的事件發生。

2:使用随機數打亂數組順序

這個案例應用的最好場景就是紙牌遊戲中的洗牌操作,思想也比較簡單,就是依次将數組内的每個元素與一個随機序号的元素進行交換。代碼如下:

void Shuffle(int[] cards)
{
    for(i=0;i<cards.Length;i++)
    {
        int temp=cards[i];
        int randomIndex=Random.Range(0,cards.Length);
        cards[i]=cards[randomIndex];
        cards[randomIndex]=temp;
        }
}      

3:使用随機數在數組中無重複的選擇元素

在機率論中我們常常見到這樣題目:一個球隊10個人,要選擇5個人去參加比賽。在遊戲中的應用場景為你希望在幾個不同的點随機生成一個不相同的NPC。例如需要在10個NPC中随機選擇5個,第一個NPC被選中的機率為5/10,如果第一個被選中了那麼第二個被選中的機率就變成了4/9,如果第一個被淘汰那麼第二個被選中的機率就為5/9

Transform[] spawnPoints;
Transform[] ChooseSet(int numRequired)
{
    Transform [] result=new Transform[numRequired];
    Int numToChoose=numRequired;
    for(int numLeft=spawnPoints.Length;numLeft>0;numLeft--)
    {
        float prob=(numToChoose+0.0)/(numLeft+0.0);
        if(Random.value<=prob)
        {
            numToChoose--;
            result[numToChoose]=spawnPoints[numLeft-1];
            if(numToChoose==0)
            break;
    }
}
return result;
}
              

過程描述:掃描待選擇的NPC數組,如果生成的随機數小于被選中的機率則表示該元素被選中,直到所需要的元素個數都被選中。

注意點:進行選擇的時候應該先将待選擇的NPC數組進行“洗牌“操作。