Unity中的Unistorm3.0天气系统笔记

news2025/1/16 20:06:54

Unistorm是Unity中的一个天气系统,它功能强大,效果优美。本文所述UniStorm为3.0版本,仅用于学习之用。

一、如何设置【白天】、【黑夜】和【天气类型】?

在Running模式下,按下Esc按键,会【弹出】或者【隐藏】天气设置界面

  • 第一个滑动条为:当下的时辰【对应从早到晚的进度】
  • 第二个下拉框为:天气的类型
  • 第三个按钮:确定按钮
    在这里插入图片描述

二、如何禁用时间流淌(Time Flow)功能?

有时候,用户操作的慢了,天气突然从白天变成黑夜,乌漆嘛黑的伸手不见五指。为了防止这种尴尬,所以有时候需要关闭时间流淌的功能。
【UniStorm System】->【Time】->【Time Flow】 设置成[Disabled]
在这里插入图片描述

三、模拟飞机在云团中穿行时,如何制作一个全景包围球?

需求:UniStorm中的天空盒是一个半球,如果要模拟飞机在云团中穿行,那么需要一整个球把飞机包住。
解决:在运行状态下,再复制出一个天气半球,并设置两个半球是合在一起的。
在这里插入图片描述

(1)云层的天空半球

/// <summary>
/// 云层组件
/// </summary>
[Header("云层组件")]
public GameObject UniStormClouds;

(2)复制天空半球,设置对原来的球的对面,让两个半球合拢成一个球。
参数为硬编码,提前在Editor的running模式下,手工操作一遍,然后保存这些参数。

private void CreateUniStormClouds()
{
    var uniStormCloudsClone = GameObject.Instantiate(UniStormClouds);
    uniStormCloudsClone.transform.parent = UniStormClouds.transform.parent;
    uniStormCloudsClone.transform.localPosition = new Vector3(-0.06383133f, -293f, -223f);
    uniStormCloudsClone.transform.rotation = Quaternion.Euler(90, 0, 0);
    uniStormCloudsClone.transform.localScale = new Vector3(1000000, 1000001, 700000);
}

四、如何关闭鼠标控制相机转动的功能

相机上挂在了一个脚本【Pause】,把这个脚本禁用即可。
天气系统自带的【相机旋转功能】可能会与【祖传的角色控制功能】冲突,所以需要禁用。
在这里插入图片描述

五、按【Esc】键的时候,天气设置界面不再显示和隐藏,如何实现?

场景初始化之后,会自动生成一个叫【UniStorm Canvas】的UI界面。
在这里插入图片描述

(1)简单粗暴的解决方法:在启动的时候,抓取这个对象,然后把他们隐藏掉。

	//等待几秒初始化后,找到UniStorm Canvas组件,然后隐藏
	var UniStormCanvas = GameObject.FindObjectsOfType<Canvas>(true).First(x => x.name == "UniStorm Canvas");
	 UniStormCanvas.gameObject.SetActive(false);

(2)最优的实现:插件已经提供这个功能的【启用】和【禁用】参数了

在这里插入图片描述

(3)正常的操作就是先找到UI,然后在关闭该选项

/// <summary>
/// 获取设置天气的三个UI元素
///     时辰-slider
///     天气类型-dropdownList
///     确定更改-button
/// </summary>
/// <param name="ctk"></param>
/// <returns></returns>
private async UniTask GetUiElements(CancellationToken ctk)
{
    //【1】等待一段时间进行初始化
    await UniTask.DelayFrame(2,cancellationToken:ctk);

    //【2】获取用来设置天气的3个UI组件
    var UniStormCanvas = GameObject.FindObjectsOfType<Canvas>(true).First(x => x.name == "UniStorm Canvas");
    TimeSlider = UniStormCanvas.GetComponentsInChildren<Slider>(true).Where(x => x.name == "Time Slider")
        .First();
    WeatherDropdown = UniStormCanvas.GetComponentsInChildren<Dropdown>(true)
        .Where(x => x.name == "Weather Dropdown").First();
    ChangeWeatherBtn = UniStormCanvas.GetComponentsInChildren<Button>(true)
        .Where(x => x.name == "Change Weather Button").First();

    //【3】关闭设置菜单
    unistorm.UseUniStormMenu = UniStormSystem.EnableFeature.Disabled;
}

六、如何通过代码更换天气

在不破坏UniStorm工程文件的前提下,思路:
1、在运行时获取设置天气的UI元素,
2、赋值【时辰】和【天气类型】,激发【确定】按钮的click事件。

#if UNITY_EDITOR
[ContextMenu("天气设置")]
#endif
async UniTask test4()
{
	Setweather();
}

private async UniTask Setweather()
{
	await UniTask.Delay(TimeSpan.FromSeconds(2f));
	
	//找到组件
	var UniStormCanvas = GameObject.FindObjectsOfType<Canvas>(true).First(x => x.name == "UniStorm Canvas");
	Debug.Log(UniStormCanvas);
	TimeSlider = UniStormCanvas.GetComponentsInChildren<Slider>(true).Where(x => x.name == "Time Slider").First();
	WeatherDropdown = UniStormCanvas.GetComponentsInChildren<Dropdown>(true).Where(x => x.name == "Weather Dropdown").First();
	ChangeWeatherBtn = UniStormCanvas.GetComponentsInChildren<Button>(true).Where(x => x.name == "Change Weather Button").First();
	
	//设置value
	TimeSlider.value = 0.5f;
	WeatherDropdown.SetOption("Thunderstorm");
	ChangeWeatherBtn.onClick.Invoke();
}

七、UniStorm的主要入口脚本

【UniStorm System】物体上有一个叫UniStormSystem的主脚本
【UniStorm Demo Player】物体和它的子物体下面有一些相机对应的功能
如果要读源码应该从UniStormSystem.cs下手

八、附录——天气控制的脚本

(1)获取天空半球,获取设置天气的UI元素,简单设置天气

namespace AsyncStep
{
    /// <summary>
    /// 获取天气设置的组件
    /// </summary>
    public class SetWeatherV3 : MonoBehaviour
    {
        /// <summary>
        /// 云层组件
        /// </summary>
        [Header("云层组件")] public GameObject UniStormClouds;

        /// <summary>
        /// 效果相机
        /// </summary>
        [Header("效果相机")] public Camera effectCamera;

        /// <summary>
        /// 地形
        /// </summary>
        [Header("地形")] public Terrain MyTerrain;

        /// <summary>
        /// 天气系统主脚本
        /// </summary>
        [Header("天气系统主脚本")] public UniStormSystem unistorm;

        /// <summary>
        /// 天气类型
        /// </summary>
        [Header("天气类型-测试用")]public string weatherType = "Thunderstorm";

        /// <summary>
        /// 时间设置
        /// </summary>
        [Header("======运行时自动获取UI组件======")] [Header("时间设置")]
        public Slider TimeSlider;

        /// <summary>
        /// 天气种类
        /// </summary>
        [Header("天气种类")] public Dropdown WeatherDropdown;

        /// <summary>
        /// 确认按钮
        /// </summary>
        [Header("确认按钮")] public Button ChangeWeatherBtn;

        void Start()
        {
            GetUiElements(this.GetCancellationTokenOnDestroy());
        }

        /// <summary>
        /// 获取设置天气的三个UI元素
        ///     时辰-slider
        ///     天气类型-dropdownList
        ///     确定更改-button
        /// </summary>
        /// <param name="ctk"></param>
        /// <returns></returns>
        private async UniTask GetUiElements(CancellationToken ctk)
        {
            //【1】等待一段时间进行初始化
            await UniTask.DelayFrame(2,cancellationToken:ctk);

            //【2】获取用来设置天气的3个UI组件
            var UniStormCanvas = GameObject.FindObjectsOfType<Canvas>(true).First(x => x.name == "UniStorm Canvas");
            TimeSlider = UniStormCanvas.GetComponentsInChildren<Slider>(true).Where(x => x.name == "Time Slider")
                .First();
            WeatherDropdown = UniStormCanvas.GetComponentsInChildren<Dropdown>(true)
                .Where(x => x.name == "Weather Dropdown").First();
            ChangeWeatherBtn = UniStormCanvas.GetComponentsInChildren<Button>(true)
                .Where(x => x.name == "Change Weather Button").First();

            //【3】关闭设置菜单
            unistorm.UseUniStormMenu = UniStormSystem.EnableFeature.Disabled;
        }

#if UNITY_EDITOR
        [ContextMenu("天气设置")]
#endif
        async UniTask test4()
        {
            Setweather();
        }

        private async UniTask Setweather()
        {
            //设置value
            TimeSlider.value = 0.5f;
            WeatherDropdown.SetOption(weatherType);
            ChangeWeatherBtn.onClick.Invoke();
        }
    }
}

(2)设置天气类型

在这里插入图片描述

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using static txlib;

namespace AsyncStep
{
    /// <summary>
    /// 天气控制:天气类型 + 日期时刻
    /// </summary>
    public class SetWeatherInfoControl : MonoBehaviour, IFlowAsync
    {
        /// <summary>
        /// 天气组件
        /// </summary>
        [Header("天气组件")] public SetWeatherV3 weather;

        /// <summary>
        /// 时间点
        /// </summary>
        [Header("时间点")] public float sliderValue;

        /// <summary>
        /// 天气类型
        /// </summary>
        [Header("天气类型")] public string weatherType;

        /// <summary>
        /// 本步骤的名字:Start中预先缓存,防止报空
        /// </summary>
        public string this_name;

        // Start is called before the first frame update
        void Start()
        {
            this_name = this.name;
        }

#if UNITY_EDITOR
        [ContextMenu("测试")]
#endif
        void Test()
        {
            FlowAsync(this.GetCancellationTokenOnDestroy());
        }

        public async UniTask FlowAsync(CancellationToken ctk)
        {
            try
            {
                weather.TimeSlider.value = sliderValue;
                Debug.Log(weather.TimeSlider.value);

                //设置value
                weather.TimeSlider.value = sliderValue;
                weather.WeatherDropdown.SetOption(weatherType);
                weather.ChangeWeatherBtn.onClick.Invoke();
            }
            catch (Exception e)
            {
                Debug.Log($"{this_name}报错:{e.Message}");
                Debug.Log($"\n 抛出一个OperationCanceledException");
                throw new OperationCanceledException();
            }

            Debug.Log($"{this.name} 执行完毕");
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/926567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python所有方向的学习路线图,萌新少走弯路!!

在放学习路线之前&#xff0c;我先来讲一下这个学习路线图有什么作用&#xff0c;避免有些新手看得云里雾里的。 学习路线图上面写的是某个方向建议学习和掌握的知识点汇总&#xff0c;举个例子&#xff0c;如果你要学习爬虫&#xff0c;那么你就去学Python爬虫学习路线图上面的…

word文档怎么压缩大小?文件压缩方法分享

Word文档是工作和学习中常用的格式&#xff0c;有时候在编辑外后发现文档体积太大了&#xff0c;想要分享或者上传到平台都不行&#xff0c;今天就给大家总结了几个Word文档压缩方法&#xff0c;轻松帮助大家解决Word文档过大的问题&#xff01; 一、压缩Word中的图片 通常情况…

Linux 下 Java Socket 编程报 java.net.Exception:Permission denied (权限不足)

本人用Linux部署springboot项目时遇见这个错误&#xff0c;原因很简单&#xff0c;就是端口号没有选对。 在linux系统中&#xff0c;端口号再1024以下的需要root权限&#xff0c;只要把端口改成大于1024的就可以了&#xff0c;但避开一些软件的默认端口&#xff0c;如Tomcat的8…

Mybatis的综合案例-学生信息查询系统 用于校验是否真正学习掌握了动态SQL

Mybatis的综合案例-学生信息查询系统 需求一&#xff1a;当用户输入的学生姓名不为空&#xff0c;则只根据学生信息进行查询; 当用户输入的学生姓名为空&#xff0c;且专业不为空&#xff0c;那么就根据学生专业进行学生的查询 需求二&#xff1a;查询所有id值小于5的学生信息…

【C++】右值引用,移动语义,完美转发

目录 右值引用移动语义拷贝构造与移动构造 万能引用与完美转发 右值引用 左值&#xff1a;可以出现在赋值符号的左边和右边&#xff0c;左值可以取地址。 右值&#xff1a;右值可以出现在赋值符号右边&#xff0c;不能出现在左边&#xff0c;右值不能取地址。 左值/右值引用就…

python+django+协同过滤算法-基于爬虫的个性化书籍推荐系统(包含报告+源码+开题)

为了提高个性化书籍推荐信息管理的效率&#xff1b;充分利用现有资源&#xff1b;减少不必要的人力、物力和财政支出来实现管理人员更充分掌握个性化书籍推荐信息的管理&#xff1b;开发设计专用系统--基于爬虫的个性化书籍推荐系统来进行管理个性化书籍推荐信息&#xff0c;以…

Qt XML文件解析 QDomDocument

QtXml模块提供了一个读写XML文件的流&#xff0c;解析方法包含DOM和SAX,两者的区别是什么呢&#xff1f; DOM&#xff08;Document Object Model&#xff09;&#xff1a;将XML文件保存为树的形式&#xff0c;操作简单&#xff0c;便于访问。 SAX&#xff08;Simple API for …

桥梁安全监测方法和内容是什么?

桥梁安全监测方法和内容是什么?桥梁监测是保障桥梁安全和稳定的重要手段。随着科技的进步&#xff0c;桥梁监测技术和设备不断完善&#xff0c;监测内容也越来越全面。本文万宾科技小编将为大家介绍桥梁安全监测的方法和内容&#xff0c;以期帮助大家更好地了解这一领域。 桥梁…

Zabbix技术分享——聚合图形配置指引

作为一款企业级监控工具&#xff0c;Zabbix支持提供图形化的报表和图形展示功能。用户可以使用Zabbix聚合图形&#xff08;aggregate graph&#xff09;来汇总和展示多个数据项的图形&#xff0c;将多个监控指标放在同一个图形中&#xff0c;以便更好地展示整体趋势和变化。 本…

iis站点备份以及端口号查找

文件地址 %windir%\system32\inetsrv\config

红外/可见光图像配准融合

红外/可见光图像配准融合 根据文献【1】&#xff0c;对于平行光轴的红外可见光双目配置进行图像配准&#xff0c;主要的限制是图像配准只是对特定的目标距离&#xff08;Dtarget&#xff09;有效。并排配置的配准误差 δx&#xff08;以像素表示&#xff09;的数学表达式为&…

wsl2中的ubuntu使用systemctl报错问题

显示如下错误&#xff1a;System has not been booted with systemd as init system (PID 1). Cant operate 原因在于wsl中的ubuntu不完整&#xff0c;手动安装systemctl貌似也不好用&#xff0c;可以使用等同的sysvinit命令 替换关系如下&#xff1a;

动态规划入门:斐波那契数列模型以及多状态(C++)

斐波那契数列模型以及多状态 动态规划简述斐波那契数列模型1.第 N 个泰波那契数&#xff08;简单&#xff09;2.三步问题&#xff08;简单&#xff09;3.使⽤最⼩花费爬楼梯&#xff08;简单&#xff09;4.解码方法&#xff08;中等&#xff09; 简单多状态1.打家劫舍&#xff…

测试开发板——第一个AutoSAR程序

前提 在上一篇文章中&#xff0c;已经安装好了所有软件 裸机程序 如果不想运行AutoSAR程序来测试开发板&#xff0c;也可以使用裸机程序来测试&#xff0c;具体可以参考 IARopenSDAs32k144 环境搭建_zdwen6zi的博客-CSDN博客 只需要 IAR 工具就可以完成&#xff0c;demo包我…

打家劫舍00

题目链接 打家劫舍 题目描述 注意点 如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警0 < nums[i] < 400 解答思路 最初想的是使用深度优先遍历&#xff0c;到达任意一个位置时&#xff0c;小偷想要偷窃最高金额&#xff0c;一定要选择后面第2个房…

Ubuntu设置中文

找到Settings 进入Settings&#xff0c;找到Region & Language 再找到Manage Installed Languages 点击Manage Installed Languages&#xff0c;出现弹出&#xff0c;再点击Install进行安装 按照提示输入密码 认证成功后&#xff0c;会进行Applying changes安装 点击Instal…

vscode 无法跳转第三方安装包

vscode 无法跳转第三方安装包 场景&#xff1a;使用vscode写代码时&#xff0c; 第三方的安装包无法使用ctrl 左键&#xff0c;点击进入查看&#xff0c; 不方便源码查看 解决办法&#xff1a; 使用快捷键 Ctrl Shift P&#xff0c; 进入命令搜索框搜索 setting.json 编辑…

【Linux】如何在linux系统重启或启动时执行命令或脚本(也支持docker容器内部)

如何在linux系统重启或启动时执行命令或脚本&#xff08;也支持docker容器内部&#xff09; 第一种&#xff1a;使用 systemd 服务单元在重启或启动时运行命令或脚本第二种&#xff1a;使用 /etc/rc.d/rc.local 文件在重启或启动时运行脚本或命令第三种&#xff1a;使用 cronta…

【附源码】Axure RP Pro8.0安装教程|HTML|网页设计

软件下载 软件&#xff1a;Axure版本&#xff1a;8.0语言&#xff1a;简体中文大小&#xff1a;82.53M安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨下载链接&#xff1a;https://pan.baidu.com/s/…

城市经济大脑:城市数字经济发展的核心引擎

以下内容来自于易知微官网,进入官网可了解更多详情。 注意&#xff1a;案例数据均为虚拟数据 随着数字时代的到来&#xff0c;全面推进城市数字化转型&#xff0c;构建与城市数字化发展相适应的现代化治理体系与治理能力&#xff0c;已成为推进新型智慧城市、数字中国建设的关…