君莫笑,小编是个半道出家的和尚,基础什么的真的没学过。。。
今天在Unity里要实现获取圆心为Vector3.Zero半径为Ridus的球上的一个随机的点,并且点的xyz都不为零,emmm,随机数嘛,是不是感觉so ez。。。
int pointX = 0;
int pointY = 0;
int pointZ = 0;
int pointZMaxLength
{
get
{
return (int)Mathf.Sqrt((radius * radius) - (pointX * pointX));
}
}
Public Vector3 GetPoint()
{
System.Random random = new System.Random();
while(pointX == 0)
{
pointX = random.Next(-radius, radius);
}
while(pointZ == 0 ||Mathf.Abs(pointZ) == pointZMaxLength)
{
pointZ = random.Next(-pointZMaxLength,pointZMaxLength);
}
pointY = (int)Mathf.Sqrt(radius * radius - (pointX * pointX + pointZ * pointZ));
}
然后我就。。。死机了
经多方调查,缘来。。。。random这个函数是有一个种子(seed)的,在seed不变的情况下,连续在同一范围取随机数。。。他会是一个定值。也就是说,如果我随机出pointX 为0 ,根据while的条件,程序会重新随机,然而这个重新随机出来的数必然还是0.。。。
如何破解呢?
在unity里,我们经常用GUID来取随机数的种子,直接上代码吧
int pointX = 0;
int pointY = 0;
int pointZ = 0;
int pointZMaxLength
{
get
{
return (int)Mathf.Sqrt((radius * radius) - (pointX * pointX));
}
}
Public Vector3 GetPoint()
{
byte[] buffer = Guid.NewGuid().ToByteArray();
int iSeed = BitConverter.ToInt32(buffer, 0);
System.Random random = new System.Random(iSeed );
pointX = random.Next(-radius, radius);
if(pointX == 0)
{
//这里用递归来重新取点,就是为了避开用同一个iSeed
GetPoint();
return;
}
pointZ = random.Next(-pointZMaxLength,pointZMaxLength);
if(pointZ == 0 ||Mathf.Abs(pointZ) == pointZMaxLength)
{
GetPoint();
return;
}
pointY = (int)Mathf.Sqrt(radius * radius - (pointX * pointX + pointZ * pointZ));
}
实际上业务比这个要复杂一些,上面只是提取了坑我的那一部分写了个demo。。。
基础不牢坑死猿啊=。=