分类:Unity、C#、VS2015

创建日期:2016-04-20

一、简介

Unity引擎提供的Random类可以用来生成随机数、随机点或旋转角度。

1、成员变量

seed:设置用于随机数生成器的种子。

value:返回一个随机数,在0.0(包括)~1.0(包括)之间。(只读)

insideUnitSphere:返回半径为1的球体内的一个随机点。(只读)

insideUnitCircle:返回半径为1的圆内的一个随机点。(只读)

onUnitSphere:返回半径为1的球体在表面上的一个随机点。(只读)

rotation:返回一个随机旋转角度。(只读)

2、方法

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、从数组选择随机项目

可随机挑选数组元素,是因为能够选择零到数组最大索引值(等于数组长度减去1)之间的随机整数。使用内置 Random.Range 函数就可轻松做到:

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

注意:Random.Range 从包含第一个参数但排除第二个参数的范围中返回一个值,所以在此处使用 myArray.Length 能给出正确结果。

2、用不同概率选择项目

有时候,您需要随机选择项目,但有些项目被选中的概率比其他项目大。例如,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,在这种情况下,省略了最后一条语句就无法搜索到随机点。

3、随机排序

一个普遍的游戏机制是从一组随机排序的已知项目中进行选择。例如,一副牌通常被打乱,这样就不会以可预测的顺序抓牌。您可以通过访问数组中的每个元素,并随机与数组中的其他元素交换,来打乱数组项目的顺序:-

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;
}
}

4、从一组项目中非重复选取

常见任务是从一组项目中随机挑选若干项目,同一个项目最多只能选中一次。例如,您可能想在随机复活点生成若干 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;
}

注意,尽管选择是随机的,但选择集中的项目与在原始数组中的顺序相同。如果项目排序是一次性的话,那么部分随机项目是可预见的,所以有必要在使用之前打乱数组的顺序。

5、空间中的随机点

将 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;

【Unity】6.6 Random类的更多相关文章

  1. Random类(随机数)

    前言:总是忘记怎么用.上网一查,都是些有的没的...... 最简单却最常用的方法:Random.Next方法 首先,为Random类实例化一个对象: Random n=new Random(); Ne ...

  2. .Net使用system.Security.Cryptography.RNGCryptoServiceProvider类与System.Random类生成随机数

    .Net中我们通常使用Random类生成随机数,在一些场景下,我却发现Random生成的随机数并不可靠,在下面的例子中我们通过循环随机生成10个随机数: ; i < ; i++) { Rando ...

  3. System类和Random类

    System类 成员方法: public static void gc():运行垃圾回收器 public static void exit(int status):退出垃圾回收器 public sta ...

  4. ActionScript 3.0 自写类整理笔记(十三)——Random类

    一个简单的随机函数工具类,总共提供了9种静态方法来获取不同的随机值随便写的,如果你还有什么更好的建议,请提出来,谢谢~ index.Random类:代码:public final class Rand ...

  5. Java api 入门教程 之 JAVA的Random类

    在实际的项目开发过程中,经常需要产生一些随机数值,例如网站登录中的校验数字等,或者需要以一定的几率实现某种效果,例如游戏程序中的物品掉落等. 在Java API中,在java.util包中专门提供了一 ...

  6. Random类

    Random类是随机数产生类,可以指定一个随机数的范围,然后任意产生在此范围中的数字. //================================================= // F ...

  7. JAVA的Random类[转]

    在实际的项目开发过程中,经常需要产生一些随机数值,例如网站登录中的校验数字等,或者需要以一定的几率实现某种效果,例如游戏程序中的物品掉落等. 在Java API中,在java.util包中专门提供了一 ...

  8. Math类和Random类(数学公式相关类)

    Math 类包含用于执行基本数学运算的方法,如初等指数.对数.平方根和三角函数. 常用方法: 1.static 数值类型 abs(数值类型 a)      返回 double 值的绝对值. 2.sta ...

  9. 用Random类输出验证码

    package dx; import java.text.DecimalFormat; import java.util.Random; public class DxL { //创建类 public ...

随机推荐

  1. 实现一个简单的shared_ptr

    翻看以前的代码的时候发现一个shared_ptr的简单实现. 我记得是网上的一篇例子(好像改了一点),但是又懒得找出处了 ╮(╯▽╰)╭. 觉得这份代码足以用来初步了解shared_ptr的实现了. ...

  2. VTK中的装配体(vtkAssembly)

    Actors有时也会组合在一起形成层次结构,当其中的某个Actor运动时,会影响到其他Actor的位置.例如,一个机械手臂可能由上臂.前臂.手腕和末端等部分通过关节连接起来.当上臂绕着肩关节旋转时,我 ...

  3. java的BASE64Encoder,BASE64Decoder加密与解密

    package com.app.common; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.Fi ...

  4. samba服务的高级进阶配置

    本文将学习一下几个方面的内容,将会结合具体的实验来一步步实现. 1. 用户账号的映射 2. 使用IP对客户端进行访问控制 3. 使用域名对客户端进行访问控制 4. 使用通配符对客户端进行访问控制 5. ...

  5. CSVWriter生成文件时writer.writeRecord();方法保存的文件末尾多一个空行

    一.问题,CSVWriter生成文件时使用writer.writeRecord();方法保存的文件末尾多一个空行,效果图如下: 目标结果:(去掉末尾空行) 二.关键代码如下(修改前代码): /** * ...

  6. windbg(1)

    1.http://www.cnblogs.com/huangyong9527/category/384128.html 2.http://www.cnblogs.com/pugang/category ...

  7. Docker(二):Dockerfile使用介绍

    上一篇文章Docker(一):Docker入门教程介绍了 Docker 基本概念,其中镜像.容器和 Dockerfile .我们使用 Dockerfile 定义镜像,依赖镜像来运行容器,因此 Dock ...

  8. hadoop下载地址

    hadoop下载地址 http://mirror.bit.edu.cn/apache/hadoop/common/ hadoop下载地址

  9. Fusion-io ioDrive Duo Enterprise PCIe Review

    原文地址:http://www.storagereview.com/fusionio_iodrive_duo_enterprise_pcie_review As part of StorageRevi ...

  10. 如果没有 Android 世界会是什么样子?

    2005年谷歌从安迪·鲁宾(Andy Rubin)手中收购Android系统,起初安迪·鲁宾(Andy Rubin)只是想为数码相机开发出一个更为先进的系统,所以有了 Android.但是智能手机行业 ...