聊城论坛:Unity 【随机数与随】机种子

admin 5个月前 (05-15) 科技 58 1

{随机数几乎应用于}游戏『开发【的】方方面面』,【<例如>】,(随机)生成【的】(地)图,「迷宫」,{怪物属性“等”},〖在〗Unity【中】,(使用随机数)非常方便:

 1         //
 2         // { 摘[要}:
 3         //     Return a random integer number between min [inclusive] and max [exclusive] (Read
 4         //     Only).
 5         //
 6         // ‘『“(参数)”』’:
 7         //   min:
 8         //
 9         //   max:
10         public static int Range(int min, int max);
 1         //
 2         // { 摘[要}:
 3         //     Return a random float number between min [inclusive] and max [inclusive] (Read
 4         //     Only).
 5         //
 6         // ‘『“(参数)”』’:
 7         //   min:
 8         //
 9         //   max:
10         [FreeFunction]
11         public static float Range(float min, float max);
1         //
2         // { 摘[要}:
3         //     Returns a random number between 0.0 [inclusive] and 1.0 [inclusive] (Read Only).
4         public static float value { get; }

『正常情况下使用』以上三{种完全够用了},“注”意整型【的】随机是左开『右闭【的】』。〖<当然了>〗,{你也可以使}用System.Random【中】【的】方法来随机,{可以构}造出类似于Unity【中】【的】扩展方法:

 1     static public int Range(this System.Random random, int min, int max)
 2     {
 3         return random.Next(min, max);
 4     }
 5 
 6     static public float Range(this System.Random random, float min, float max)
 7     {
 8         var r = random.NextDouble();
 9         return (float)(r * (max - min) + min);
10     }

(值得)〖注意〗【的】是,System.Random《需要实例化才能随机》,(而)UnityEngine.Random「是直接使用」。

 

(但很多)「时」候,“我们除了需要随”机数之『外』,〖可能会有〗保留上次随机【结<果>】【的】需求,〖换句话说〗,『从某』一「时」刻起,「我们希望每次」都能随机『出和』上次相同【的】结<果>,「这“个”「时」候就」该【随机种子】{出场了}。

「举例来说」,<当玩家需要重新进>入一 次他以前随机出来[过【的】一“个”「迷宫」(地)图进行二次<创作>,【又比如】,我们〖在〗开发过程【中】,{某“个”随机}单位出现了Bug,《但如<果>下次又没法产生》“之前随机结<果>”【的】话,‘那么就会出现十分头疼’(【的】状况了), 这样很可能永远有“个”难[以排查【的】潜〖在〗Bug一直〖在〗开发过程【中】(而)又<难以再次复现>。

〖所〗以,《强烈建议》,《只》要是做相对比较复杂《【的】随机》行为,{我们最{好}利用随}机种子「来执行随机」

〖<当然了>〗,{你说我将}所有随机【的】数{据结<果>}序{列}化保存到本(地),“那也没”“问题”,“但相”比【随机种子】只需要(保存一“个”整型数据来说),哪种方式更可取显(而)易「见」。『这样也可以大大减』少游「戏保存【的】」数据容量。

 

‘说’了这么半天,【什么是【随机种子】】呢?

{顾名思义}, 一“个”种子[对应着一“个”结<果>, 随机种[子对应【的】就是一“个”唯一【的】随机结<果>。

 1         //
 2         // { 摘[要}:
 3         //     Initializes the random number generator state with a seed.
 4         //
 5         // ‘『“(参数)”』’:
 6         //   seed:
 7         //     Seed used to initialize the random number generator.
 8         [NativeMethod("SetSeed")]
 9         [StaticAccessor("GetScriptingRand()", StaticAccessorType.Dot)]
10         public static void InitState(int seed);

上面【的】方法【中】,‘『“(参数)”』’seed「就是传入【的】随」机种子,如<果>〖在〗脚本【的】一开始执 行调用了此[方法,<那么只有当此次随>机种‘子与上’次【的】种子不相同「时」,『才能随机出不同【的】』随机结<果>,否则随机【的】结<果>总是一‘样【的】’。

〖注意〗,这里指【的】随机结<果>是指【的】所有【的】随机结<果>, 是一“个”随机数[表,它从本质上<改>变【的】是整“个”UnityEngine.Random类【的】所有随机方法执行【的】结<果>,包括最开始{列}举【的】三种【中】【的】任意一种。

下面做一“个”测试就很容【易理】解了:

 1 using UnityEngine;
 2 
 3 public class RanTest : MonoBehaviour
 4 {
 5     public bool bDebug;
 6     //System.Random random;
 7     void Start()
 8     {
 9         //random = new System.Random((int)System.DateTime.Now.Ticks);
10         //string s = "";
11         //for(int i = 0; i < 233; i++)
12         //{
13         //    s += random.Range(0, 10) + ",";
14         //}
15         //Debug.Log(s);
16 
17         int seed = (int)System.DateTime.Now.Ticks;
18         if (bDebug)
19         {
20             seed = PlayerPrefs.GetInt("Seed");   
21         }
22         else
23         {
24             PlayerPrefs.SetInt("Seed", (int)System.DateTime.Now.Ticks);
25         }
26         Random.InitState(seed);
27         string s = "";
28         for (int i = 0; i < 32; i++)
29         {
30             s += Random.Range(0, 10) + ",";
31         }
32         Debug.Log(s);
33     }
34 }

比如我开了一“个”Debug‘模式’,如<果>勾选,{则【随机种子】是从}上次保存【的】数据【中】读取,随机出来【的】结<果>永远是一‘样【的】’,因为我并没有对保存【的】数据种子进行任何【的】更<改>。

结<果>如下:

 

我们发现每次【的】随机数(都一样),因为它们都源于同一“个”【随机种子】,(无论之)后再随机多少次,结<果>都是这“个”随机数序{列},这“个”种子对应【的】结<果>已【经被计算机】固定了,除非种子更<改>,不然随机结<果>不会变。

“当我关闭”Debug‘模式’「时」,正常【的】【随机种子】「时」刻都(不会一样),“这里用到了”System.DateTime.Now.Ticks来保证得到和上次【的】种子绝不相同【的】整型, 也可以使[用guid“等”。

每次〖在〗本(地)备份一次上一次【随机种子】【的】记录,以便随「时」可以再现上一次随机【的】结<果>,‘只需要轻松勾选’Debug“即可”:

 

 【<例如>】,我〖在〗第三次「时」发现了随机产生【的】其他Bug,「这样我只用」启动Debug‘模式’反复分析几遍后把复现【的】隐藏Bug修<改>结束后再回到正常‘模式’产生新【的】随机数就{好}。

 

另『外』, 我们也可以利用[System.Random类【的】构造方法来实现同‘样【的】’随机效<果>,一“个”构造方法带有【随机种子】【的】‘『“(参数)”』’,一“个”则没有,原理和上面是一‘样【的】’:

 1 public Random(); 2 public Random(int Seed); 

这“个”「时」候<改>变【的】就是System.Random类【的】随机方法,(而)非UnityEngine.Random【的】随机方法。

〖所〗以一开始就决定{好}整“个”开发过程【中】用【的】随机「类也不容忽视」,‘建议’“要么就全部用”Unity【中】【的】,“要么就全部用”System【中】【的】, 这样调整起来自[然更得 心应手[事半功倍。

,

Sunbet

Sunbet www.bus123.net网络安全巴士站是一“个”〖专注于网络安全〗、<系统安全>、“互联网”安全、{信息安全},全新视界【的】“互联网”安全《新媒体》

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:聊城论坛:Unity 【随机数与随】机种子

网友评论

  • (*)

最新评论

  • 头条网 2020-05-15 03:49:03 回复

    阳光在线:www.0913esg.com(原诚信在线)现已开放阳光在线手机版下载。阳光在线游戏公平、公开、公正,用实力赢取信誉。情节不拖沓,喜欢

    1

文章归档

站点信息

  • 文章总数:439
  • 页面总数:0
  • 分类总数:8
  • 标签总数:900
  • 评论总数:123
  • 浏览总数:3178