分类:Unity、C#、VS2015 数组
建立日期:2016-04-20 dom
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); } }
随机选取项目或值在不少游戏中很是重要。该部分说明如何使用 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% 的机率会提供金钱做为礼物
能够想象这些不一样的结果分布在分红几部分的条形纸上,每种结果占总长度的一部分。所占部分与选中结果的几率相等。作选择就是选取条形纸长度上的随机点(好比说扔飞镖),而后看看它落在哪一个部分。
在脚本中,条形纸其实是一个浮点数组,按顺序包含项目的不一样几率。随机点由 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;