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

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} 执行完毕");
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

汽车自适应巡航系统车距控制策略研究

1 引言 自适应巡航控制( Adaptive Cruise Control&#xff0c;ACC) 是汽车驾驶辅助系统的重要组成部分&#xff0c;其作用是根据车距传感器探测到本车( ACC 车辆) 与主目标车辆( 前车) 之间的相对位置和相对速度信息&#xff0c;自动调节ACC 车辆的节气门开度或部分制动力矩( 即…

Spring security报栈溢出几种可能的情况

今天在运行spring security的时候&#xff0c;发现出现了栈溢出的情况&#xff0c;总结可能性如下&#xff1a; 1.UserDetailsService的实现类没有加上Service注入到容器中&#xff0c;导致容器循环寻找UserDetailsService的实现类&#xff0c;最终发生栈溢出的现象。 解决方法…

linux中安装nodejs,卸载nodejs,更新nodejs,git

注意&#xff0c;我的是Ubuntu系统 卸载nodejs 卸载node sudo apt-get remove nodejs清理掉自动安装的并且不需要软件包 sudo apt autoremove查看node相关的文件 sudo whereis node如果有文件需要手动删除文件 删除该文件命令 sudo rm -rf /usr/local/bin/node在此查看node…

oauth2.0第2季 分布式认证与授权实现单点登录

一 oauth介绍 1.0 疑问汇总 1.使用jwttoken进行令牌传输&#xff0c;资源服务器在本地怎么验证token&#xff1f; 1.1 oauth的基础内容 1.1.1 oauth是什么 1.1.2 oauth的角色 1.1.3 oauth的认证流程 1.1.4 oauth的4种模式 1.2 为何要用oauth2.0 1.介绍单体架构 使用ses…

关于stm32推挽带有上下拉电阻的思考、IO口驱动能力是什么

1、发现推挽带有上下拉电阻 1.1、stm32手册 记忆中推挽是不需要上下拉的&#xff0c;没关注过&#xff0c;但是我真的理解上下拉吗&#xff0c;下图来自stm32f4的中文版和英文版的数据手册&#xff0c;没有翻译错&#xff0c;就是“推挽带有上下拉的能力”。 1.2、查找相关信…

如何向BertModel增加字符

这里写自定义目录标题 看起来add_special_tokens和add_tokens加入的新token都不会被切分。

Java实现根据按图搜索商品数据,按图搜索获取1688商品详情数据,1688拍立淘接口,1688API接口封装方法

要通过按图搜索1688的API获取商品详情跨境属性数据&#xff0c;您可以使用1688开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例&#xff0c;展示如何通过1688开放平台API获取商品详情属性数据接口&#xff1a; 首先&#xff0c;确保您已注册成为1688开放平台…

镜之Json Compare Diff

前言 “镜” 寓意是凡事都有两面性,Json 对比也不例外! 因公司业务功能当中有一个履历的功能,它有多个版本的 JSON 数据需要对比出每个版本的不同差异节点并且将差异放置在一个新的 JSON 当中原有结构不能变动,差异节点使用数组对象的形式存储,前端点击标红即可显示多个版本的节…

【STM32】学习笔记-江科大

【STM32】学习笔记-江科大 1、STM32F103C8T6的GPIO口输出 2、GPIO口输出 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口可配置为8种输入输出模式引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V输出模式下可控制端口输出高低电平&#…

Arduino RGBLED灯 模块学习与使用

Arduino RGBLED灯模块学习与使用 硬件原理制作衍生连接线Mixly程序Arduino程序演示视频 人生如逆旅&#xff0c;我亦是行人。 —— 苏轼江客:时荒 硬件原理 RGBLED灯三个引脚分别控制三个LED灯的亮度&#xff0c;RGB分别是red&#xff0c;green&#xff0c;blue的英文缩写&…

数据库的基本概念

数据库 数据库由表集合组成&#xff0c;它是以一定的组织方式存储的相互有关的数据集合。 表&#xff1a;记录&#xff1a;行&#xff0c;字段&#xff08;属性&#xff09;&#xff1a;列&#xff0c;以行列的形式就组成了表&#xff08;数据存储在表中&#xff09;。 关系数…

【MySQL】组合查询

目录 一、组合查询 1.创建组合查询 2.union规则 3.包含或取消重复的行 4.对组合查询结果排序 一、组合查询 多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询&#xff08;多条SELECT语句&#xff09;&#xff0c;并将结果作为单个查…

Unity之 Vector3 的详细介绍以及方法的介绍

文章目录 总的介绍小试牛刀相关的描述的参数看个小例子 总的介绍 当涉及到Unity中的Vector3类时&#xff0c;以下是一些常用的方法和操作&#xff1a; magnitude 方法&#xff1a;返回向量的长度。 float length vector.magnitude;sqrMagnitude 方法&#xff1a;返回向量的平…

2013.8.5-2023.6.2碳排放权交易数据集

2013.8.5-2023.6.2碳排放权交易数据集 1、时间&#xff1a;2013.8.5-2023.6.2 2、指标&#xff1a;行政区划代码、所属省份、所属地域、长江经济带、经度、纬度、交易日期、地区、交易品种、开盘价、最高价、最低价、成交均价、收盘价、前收盘价、涨跌幅_%、总成交量、总成交…

启英泰伦通话降噪方案,采用深度学习降噪算法,让通话更清晰

生活中的通话应用场景无处不在&#xff0c;如电话、对讲机、远程会议、在线教育等。普遍存在的问题是环境噪音、干扰声导致通话声音不清晰&#xff0c;语音失真等。 为了解决这一问题&#xff0c;启英泰伦基于自适应线性滤波联合非线性滤波的回声消除方案和基于深度学习的降噪…

Rancher上的应用服务报错:413 Request Entity Too Large

UI->rancher的ingress->UI前端(在nginx里面)->zuul->server 也就是说没经过一次http servlet 都要设置一下大小 1.rancher的ingress 当出现Request Entity Too Large时&#xff0c;是由于传输流超过1M。 1、需要在rancher的ingress中设置参数解决。 配置注释&a…

RabbitMQ的镜像队列

镜像队列 如果 RabbitMQ 集群中只有一个 Broker 节点&#xff0c;那么该节点的失效将导致整体服务的临时性不可用&#xff0c;并且也可能会导致消息的丢失。可以将所有消息都设置为持久化&#xff0c;并且对应队列的durable 属性也设置为 true &#xff0c;但是这样仍然无法…

15-mongodb

一、 MongoDB 简介 1 什么是 MongoDB MongoDB 是一个基于分布式文件存储的数据库。由 C语言编写。在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系…

[FlareOn6]Snake 题解

这是是一个后缀为.nes的文件&#xff0c;NES&#xff08;Nintendo Entertainment System&#xff0c;任天堂娱乐系统&#xff09; 找到一个工具FCEUX可以打开和调试 打开十六进制编辑器观察数值的变化 发现0x25处记录了记录了吃掉苹果的个数 在这个地方打一个硬件断点 运行一…