IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity Random 随机数测试 -> 正文阅读

[游戏开发]Unity Random 随机数测试

近期工作中需要完成一个基于局域网的双人联机游戏原型,游戏中需要两个客户端同步随机结果。由于只是展示用的原型,不需要校验,故我决定使用随机数种子保证随机的结果一致,在进入游戏时使用同个种子初始化。

我写了个简单的测试脚本进行测试,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 测试随机数种子的使用方法
/// 主要用于多客户端同步
/// </summary>
public class RandomTest : MonoBehaviour
{
    public Text txtLog;//展示测试过程

    private float timer = 0f;//即时
    private int count = 0;//计数
    private int seedIdx = 0;//种子索引计数

    //随机数种子数组
    private int[] SeedArr = new int[10] { 19971017, 19971105, 1, 337845818, 27, 64, 2, 888, 666, 7 };

    //随机范围最小值数组
    private int[] minArr = new int[10] { 0, 1, 0, 2, 1, 0, 3, 1, 0, 0 };

    //随机范围最大值数组
    private int[] maxArr = new int[10] { 1, 10, 0, 3, 4, 10, 9, 999, 9999, 1 };
    // Start is called before the first frame update
    void Start()
    {
        txtLog.text = "";
        InitSeed();//开始时先初始化一次
    }

    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;
        if (timer >= 1f)//每秒展示一次随机数
        {
            timer -= 1f;//使用这样的写法,不将timer直接设为0f,可以避免累积计时误差(但其实99%的情况下无所谓)。
            ShowRandomNum();
        }
    }
    private void InitSeed()//(重新)设置随机数种子
    {
        txtLog.text += $"重设随机种子为{SeedArr[seedIdx % 10]}\n";
        Random.InitState(SeedArr[seedIdx % 10]);
        seedIdx++;
    }
    private void ShowRandomNum()//展示一次随机结果
    {
        count++;
        int rangeIdx = (count - 1) % 10;
        if (count % 5 == 0)
        {
            InitSeed();
        }
        int r = Random.Range(minArr[rangeIdx], maxArr[rangeIdx]);
        Debug.Log($"第{count}次随机,随机范围:({minArr[rangeIdx]},{maxArr[rangeIdx]}), 数值为{r}");
        txtLog.text = txtLog.text + r.ToString() + "\n";
    }
}

代码会根据写死在数组里的数值定期重设随机数种子,每隔1秒会根据数组中配置的随机范围去随机一个int值。这样,每个客户端第n次随机的范围、种子都是一致的,也就模拟了原型中同步随机结果的需求。(由于每次随机相关操作是每个客户端都会执行的,所以在不需要校验的原型项目中,可视为所有客户端每次随机的范围一致。)

打包、双开测试效果如图:
(其实重设随机数种子的时机靠前了一步,但不影响测试结论。)
结论:当使用 UnityEngine.Random 类的 InitState(int seed);方法后,不同客户端的同一次、同范围的随机结果是相同的。

正式项目中也可由服务器发给同一场游戏的每个客户端同个随机数种子,这样每个客户端的“演出”结果就可保证一致。

如有漏洞或错误,欢迎讨论、指正。

(至此的测试结果已经能满足我的简单需求,稍后可能会进行更全面的测试。)

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-11-23 12:41:48  更:2021-11-23 12:43:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 23:54:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码