新增隨機的遊戲元素

2021-07-02 23:47:27 字數 3400 閱讀 5896

文件路徑:unity manual / unity overview / creating gameplay / adding random gameplay elements

在許多遊戲裡,隨機地選擇物品或者數值是很重要的。本節展示了你該如何通過 unity 內建的隨機函式來實現一些常見的遊戲機制。

隨機地選擇乙個陣列元素,可以歸結為隨機地選擇乙個範圍從0到陣列最大下標(這個值等於陣列的長度減去1)的整數。這項工作可以很輕鬆地借助內建的 random.range 函式來完成:

var element = myarray[random.range(0, myarray.length)];
請注意,random.range 返回乙個取值範圍包含第乙個引數但不包含第二個引數的值。因此此處使用 myarray.length 可以給出正確的結果。

有時候,你需要隨機地選擇物品,且其中某些物品被選中的可能性相比另一些物品更大一些。舉例來說,某個npc可能以如下的多種不同方式與遇到的玩家進行互動:

你可以將這些不同的結果視覺化為乙個紙帶,這個紙帶被分割為各個切片,每個切片佔據了紙帶總體長度的一部分。所佔據的部分等於該結果被選中的機率。如此一來,做選擇就等價於選擇帶子上的乙個隨機位置點(就像扔飛鏢那樣),然後看這個點落在哪一部分。

在指令碼中,這個紙帶實際上是乙個浮點數陣列,這個陣列依次包含了各個物品的不同選中概率。這個隨機點是通過將 random.value 乘以陣列中所有浮點數的和得到(陣列中的浮點數之和不必非得是1;關鍵在於不同值之間的相對大小)。為了找到隨機點落在哪個陣列元素中,我們首先檢查該值(random.value 乘以浮點數之和)是不是小於陣列中的第乙個元素。如果是的話,那麼第乙個元素就是被選中的幸運兒。否則,將該值減去第乙個元素的值,然後比較更新後的值與第二個元素的大小。重複這個過程,直到找到正確的元素。這件事用**描述看起來如下:

//js 

function choose(probs: float)

var randompoint = random.value * total;

for (i = 0; i < probs.length; i++)

return probs.length - 1;

}

//c#

float choose (float probs)

float randompoint = random.value * total;

for (int i= 0; i < probs.length; i++)

else

}return probs.length - 1;

}

請注意,末尾的 return 語句是不可缺少的,因為 random.value 可能返回 1 作為結果。如果是這種情況,那麼搜尋將會找不到隨機位置點的落點位置。假如將這行

if (randompoint < probs[i])
改為

if (randompoint <= probs[i])
那麼雖然能免去末尾的 return 語句,但是卻會允許偶爾選中乙個概率被設定為零的物品。

乙個常見的遊戲機制就是從已知的一堆物品裡以亂序取出它們。例如,一整副撲克牌通常會被打亂,這樣抽牌的順序就無法被**。你可以通過訪問每乙個元素並與其他隨機下標的元素進行交換的方式來打亂陣列中的元素。示例**如下:

//js

function shuffle(deck: int)

}

//c#

void shuffle (int deck)

}

乙個常見的任務就是從一堆物品中不重複地、隨機地取出一些物品,每個物品最多被選中一次。例如,你可能想在隨機的重生點生成一些npc,但是每個重生點僅乙個npc。這可以通過順序地在物品上進行重複地做隨機決定該物品是否要加入到被選中集合中來實現。對於每個被訪問的物品,該物品被選中的概率等於剩餘需要選中物品數量除以剩餘候選物品數量。

舉個例子,假設有十個重生點可供選擇,而只需挑選其中的五個。那麼第乙個物品被選中的概率是 5/10 或者說是 0.5. 如果它被選中了,那麼第二個物品被選中的概率就是 4/9 或者說是 0.44(還需要4個物品,剩餘9個可供選擇).否則第二個物品被選中的概率是 5/9 或者說是 0.56(還需要5個物品,剩餘9個可供選擇).重複這個操作直到被選中集合含有5個物品。你可以用如下的**來完成這項工作:

//js

var spawnpoints: transform;

function chooseset(numrequired: int)

}return result;

}

//c#

transform spawnpoints;

transform chooseset (int numrequired) }}

return result;

}

請注意,雖然選擇是隨機的,但是被選中集合中的物品依然是原集合中的順序。如果這些物品是按順序地每次逐個使用的話,那麼這些物品的順序有可能導致它們被部分地**。因此,在使用前可能還需要打亂這個被選中集合陣列。

立方體內的隨機點可以通過將 vector3 的每個分量分別設定為 random.value 的返回值來達成,**如下:

var randvec = 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;

實現遊戲骨架 新增基本的介面元素

到目前,我們的 棋路 中國象棋 遊戲已經有些眉目了!為了不至於太緊張,在做了一大堆複雜工作後,現在是做點輕鬆且有成效的工作的時間了!本節讓我們來給象棋遊戲新增基本的介面元素!static const statusbarheight 28.0 我們先為遊戲新增乙個開始選單頁面 在 lib routes...

簡單的隨機遊戲

首先,建乙個類moragame 1 封裝屬性 public class moragame system.out.println 請輸入你的名字 playername sc.next system.out.println playername vs this.computername 3 開始遊戲 開...

陣列元素的隨機排序

function randomorder targetarray var arraylength targetarray.length 目標陣列的長度 var temparray1 new array 先建立乙個正常順序的陣列 for var i 0 i arraylength i 將目標陣列的元素...