Unity实现日夜交替效果详解
创作时间:
作者:
@小白创作中心
Unity实现日夜交替效果详解
引用
51CTO
1.
https://blog.51cto.com/u_16213662/12928413
本文将介绍如何在Unity中实现日夜交替效果。通过本教程,你将学习到如何使用Universal RP插件、编写相关脚本以及搭建场景来实现这一效果。
一、效果展示
(此处应有效果展示图片,但原文中未提供具体图片)
二、前期准备
1、创建一个2D的项目
2、下载Universal RP插件(Window->Package Manager)
3、添加渲染器
三、场景搭建
四、代码
1、WorldTimeConstants.cs(用来存储公共变量)
public static class WorldTimeConstants
{
public const int MinutesInDay = 1440; //一天一共有多少分钟
}
2、WorldTime.cs(挂载在空物体上)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System; //引入命名空间
public class WorldTime : MonoBehaviour
{
public event EventHandler<TimeSpan> WorldTimeChanged; //事件
[SerializeField] //用于使私有字段也能在Inspector中显示
private float _dayLength;
private TimeSpan _currentTime;
private float _minuteLength => _dayLength / WorldTimeConstants.MinutesInDay;
private void Start()
{
StartCoroutine(AddMinute());
}
private IEnumerator AddMinute()
{
_currentTime += TimeSpan.FromMinutes(1);
WorldTimeChanged?.Invoke(this, _currentTime); //通知其他脚本游戏时间已经发生了变化
yield return new WaitForSeconds(_minuteLength); //用于每隔一定时间(_minuteLength)将游戏世界的时间增加一分钟
StartCoroutine(AddMinute()); //实现循环增加游戏时间的效果
}
}
3、WorldTimeDisplay.cs(挂载在时间文本上)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

using System;
/// <summary>
/// 表示在挂载该脚本的 GameObject 上必须要有一个 TMP_Text 组件,
/// 否则会自动添加一个。这样就保证了在使用该脚本时,TMP_Text 组件一定存在,
/// 避免了在运行时出现空引用的情况。
/// </summary>
[RequireComponent(typeof(TMP_Text))]
public class WorldTimeDisplay : MonoBehaviour
{
[SerializeField]
private WorldTime _worldTime;
private TMP_Text _text;
private void Awake()
{
_text = GetComponent<TMP_Text>();
_worldTime.WorldTimeChanged += OnWorldTimeChanged; //订阅事件
}
private void OnDestroy()
{
_worldTime.WorldTimeChanged -= OnWorldTimeChanged; //取消订阅
}
private void OnWorldTimeChanged(object sender, TimeSpan newTime)
{
_text.SetText(newTime.ToString(@"hh\:mm"));
}
}
4、WorldLight.cs(挂载在光源上)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering.Universal; //需导入资源Universal RP
[RequireComponent(typeof(Light2D))]
public class WorldLight : MonoBehaviour
{
private Light2D _light;
[SerializeField]

private WorldTime _worldTime;
[SerializeField]
private Gradient _gradient; //用于创建一组渐变色
private void Awake()
{
_light = GetComponent<Light2D>();
_worldTime.WorldTimeChanged += OnWorldTimeChanged;
}
private void OnDestroy()
{
_worldTime.WorldTimeChanged -= OnWorldTimeChanged;
}
private void OnWorldTimeChanged(object sender, TimeSpan newTime)
{
_light.color = _gradient.Evaluate(PercentOfDay(newTime));
}
private float PercentOfDay(TimeSpan timeSpan)
{
//timeSpan.TotalMinutes表示时间跨度(时间差)所代表的分钟数,返回一个双精度浮点数类型。
//例如,如果一个 TimeSpan 实例的值为 02:30:00(2 小时 30 分钟),则调用 TotalMinutes 属性将返回 150.0。
return (float)timeSpan.TotalMinutes % WorldTimeConstants.MinutesInDay / WorldTimeConstants.MinutesInDay;
}
}
5、WorldTimeWatcher.cs(挂载在图标上)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.Events;
using System.Linq;
public class WorldTimeWatcher : MonoBehaviour
{
[SerializeField]
private WorldTime _worldTime;
/// <summary>
/// 用于告诉C#编译器可以对标记为该特性的类、结构体、枚举进行序列化和反序列化操作。
/// 在Unity中,这个特性常常用于标记自定义的数据结构,
/// 以便在Inspector面板中可以直接显示和编辑。
/// </summary>
[Serializable]
private class Schedule
{

public int Hour;
public int Minute;
public UnityEvent _action;
}
[SerializeField]
private List<Schedule> _schedule;
// Start is called before the first frame update
void Start()
{
_worldTime.WorldTimeChanged += CheckSchedule;
}
private void OnDestroy()
{
_worldTime.WorldTimeChanged -= CheckSchedule;
}
private void CheckSchedule(object sender, TimeSpan newTime)
{
//FirstOrDefault 方法,查找 _schedule 列表中第一个满足指定条件的元素
var schedule =
_schedule.FirstOrDefault(s =>
s.Hour == newTime.Hours
&& s.Minute == newTime.Minutes);
schedule?._action?.Invoke();
}
}
热门推荐
地质学中与矿物、地层及地球内部构造有关的诸多因素探讨
月亮之母:忒伊亚与地球板块运动之谜
生命起源之谜:地球自身的产物还是外星生物?
丹皮:传统中药的神奇功效揭秘
《百城头牌菜》带你探秘千岛湖美食文化
千岛湖必打卡:鱼头泡饼&渔家乐
双十一剁手党必备:慢跑治鼻炎
持续性咳嗽竟是鼻炎在作祟?教你区分和治疗
冬季鼻炎患者的饮食良方:蜂蜜配胡萝卜
鼻炎福音:权威推荐鼻腔冲洗疗法
寒热错杂用泻心,胃气郁滞选胃苏:中医辨治胃痛有讲究
武汉至厦门自驾游,六日美景不容错过
阜外华中心血管病医院教你预防甲状腺结节
甲状腺结节治疗新选择:手术还是放射性碘治疗?
索尼PS3经典版本大揭秘:哪款值得收藏?
科学解读逍遥丸:妇科良药的适用与禁忌
烘焙达人教你选红糖or黑糖
频繁做梦影响睡眠,5个实用方法助你深度休息
红糖PK黑糖:谁才是养生界的C位?
深圳:从渔村到国际大都市的历史见证
春天修剪有讲究,掌握这几个窍门,花儿蹭蹭长!
春三月绣球花管理做好这5点,花开满盆,人人夸!
大叶万年青分盆成活技巧(万年青分盆的注意事项及育苗要点)
生化诊断中腺苷脱氨酶的检测意义
全球十大最宜居城市,4个在欧洲!移居欧洲有哪些方式?
奥地利湖区之美,不只在哈尔施塔特
湖北邮政创新融合文旅发展,助力“知音湖北”品牌建设
警惕“道德绑架”概念滥用,别让社会善意寒了心
广州发布2035交通规划:打造国际枢纽,构建湾区一小时交通圈
檀溪路到鹿门寺最便捷公交路线攻略:53路直达,无需换乘