【Unity】6.6 Random類

分類:Unity、C#、VS2015 數組

建立日期:2016-04-20 dom

1、簡介

Unity引擎提供的Random類能夠用來生成隨機數、隨機點或旋轉角度。 ide

一、成員變量 函數

seed:設置用於隨機數生成器的種子。 ui

value:返回一個隨機數,在0.0(包括)~1.0(包括)之間。(只讀) spa

insideUnitSphere:返回半徑爲1的球體內的一個隨機點。(只讀) code

insideUnitCircle:返回半徑爲1的圓內的一個隨機點。(只讀) orm

onUnitSphere:返回半徑爲1的球體在表面上的一個隨機點。(只讀) blog

rotation:返回一個隨機旋轉角度。(只讀) 排序

二、方法

Range:返回min和max之間的一個隨機浮點數,包含min但不包含max。

若是max等於min,將返回min。返回值永遠不會是max,除非min等於max。

例如:

using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
    public GameObject prefab;
    public void Awake() {
//從關卡列表中加載一個隨機關卡
        Application.LoadLevel(Random.Range(0, Application.levelCount));
    }
    void Start() {
        Vector3 position = new Vector3(Random.Range(-10, 10), 0, Random.Range(-10, 10));
        Instantiate(prefab, position, Quaternion.identity);
    }
}

2、基本用法--添加隨機的遊戲元素

隨機選取項目或值在不少遊戲中很是重要。該部分說明如何使用 Unity 內置隨機函數執行一些常見的遊戲機制。

一、從數組選擇隨機項目

可隨機挑選數組元素,是由於可以選擇零到數組最大索引值(等於數組長度減去1)之間的隨機整數。使用內置 Random.Range 函數就可輕鬆作到:

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

注意:Random.Range 從包含第一個參數但排除第二個參數的範圍中返回一個值,因此在此處使用 myArray.Length 能給出正確結果。

二、用不一樣機率選擇項目

有時候,您須要隨機選擇項目,但有些項目被選中的機率比其餘項目大。例如,NPC 在遇到玩家時會以幾種不一樣的方式做出反應:

l 50% 的機率會友好問候

l 25% 的機率會跑開

l 20% 的機率會當即攻擊

l 5% 的機率會提供金錢做爲禮物

能夠想象這些不一樣的結果分佈在分紅幾部分的條形紙上,每種結果佔總長度的一部分。所佔部分與選中結果的機率相等。作選擇就是選取條形紙長度上的隨機點(好比說扔飛鏢),而後看看它落在哪一個部分。

image

在腳本中,條形紙其實是一個浮點數組,按順序包含項目的不一樣機率。隨機點由 Random.value 乘以數組中全部浮點總數得出(它們合計起來不必定等於 1;重點是不一樣值得到的相對大小)。要找出隨機點「落在」哪一個數組元素,首先檢查看它是否小於第一個元素的值。若是是,則將選中第一個元素;不然,從點值減去第一個元素的值,再與第二個元素比較,直到找到正確的元素。相似於下面的C#代碼:

public float Choose(float[] probs)
    {
        float total = 0.0f;
        foreach (var elem in probs)
        {
            total += elem;
        }

        float randomPoint = Random.value * total;
        for (int i = 0; i < probs.Length; i++)
        {
            if (randomPoint <= probs[i]) return i;
            else randomPoint -= probs[i];
        }
        return probs.Length - 1;
    }

注意,最後一個返回語句不能省略,由於 Random.value 可能會返回結果 1,在這種狀況下,省略了最後一條語句就沒法搜索到隨機點。

三、隨機排序

一個廣泛的遊戲機制是從一組隨機排序的已知項目中進行選擇。例如,一副牌一般被打亂,這樣就不會以可預測的順序抓牌。您能夠經過訪問數組中的每一個元素,並隨機與數組中的其餘元素交換,來打亂數組項目的順序:-

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

四、從一組項目中非重複選取

常見任務是從一組項目中隨機挑選若干項目,同一個項目最多隻能選中一次。例如,您可能想在隨機復活點生成若干 NPC,但要確保每一個點處只能生成一個 NPC。爲此,能夠依次迭代項目,隨機決定每一個項目是否要添加到選擇集。訪問完每一個項目後,剩下項目被選中的機率等於須要選擇的項目數量除以剩下的全部項目數量。

例如,假設有十個復活點可選,但必須只能選擇五個。第一個項目被選中的機率是 5 / 10 或 0.5。若是選擇第一個項目,則第二個項目的機率爲 4 / 9 或 0.44(即仍需從九個剩下的項目中選擇四個)。然而,若是沒有選擇第一個項目,則第二個項目的機率爲 5 / 9 或 0.56(即仍需從九個剩下的項目中選擇五個)。這個操做一直持續到選擇集包含五個所需項目。

您能夠在以下代碼中完成此目的:

public Transform[] ChooseSet(int numRequired)
{
    var result = new Transform[numRequired];
    var numToChoose = numRequired;
    for (int numLeft = spawnPoints.Length; numLeft > 0; numLeft--)
    {
        // Adding 0.0 is simply to cast the integers to float for the division.
        var prob = numToChoose + 0.0 / numLeft + 0.0;

        if (Random.value <= prob)
        {
            numToChoose--;
            result[numToChoose] = spawnPoints[numLeft - 1];

            if (numToChoose == 0)
                break;
        }
    }
    return result;
}

注意,儘管選擇是隨機的,但選擇集中的項目與在原始數組中的順序相同。若是項目排序是一次性的話,那麼部分隨機項目是可預見的,因此有必要在使用以前打亂數組的順序。

五、空間中的隨機點

將 Vector3 每一個份量設爲 Random.value 返回的值,經過這種方式來選擇三維空間中的隨機點:

var randVec = new Vector3(Random.value, Random.value, Random.value);

上述函數在邊長爲一個單位的立方體中給出一個點。將向量的 X、Y 和 Z 份量乘以所需邊長,就可將立方體進行簡單的縮放。若是一個軸的值設爲零,該點將始終位於某一個平面。例如,如選擇「地面」上的一個隨機點,一般是隨機設置 X 和 Z 份量,而將 Y 份量設爲零。

當它是一個球體時(即:當您想從原點引出的給定半徑內獲取一個隨機點時),您能夠用 Random.insideUnitSphere 乘以所需半徑的大小:

var randWithinRadius = Random.insideUnitSphere * radius;

注意,若是您將結果向量的某個份量設爲零,則「不能」在一個圓內得到正確的隨機點。儘管該點確實是隨機的,且在右半徑內,但點的分佈機率在很大程度上會偏向圓的邊緣,所以點分佈極不均勻。爲完成此任務,應當使用 Random.insideUnitCircle:

var randWithinCircle = Random.insideUnitCircle * radius;

相關文章
相關標籤/搜索