Сегодня вы узнаете как создать смену дня и ночи в Unity 5. Взяв за основу наработки этого урока вы сможете внести разнообразие в вашу игру на Unity.
При первом запуске Unity 5 вы, наверняка, пробовали изменять угол освещения, который установлен по умолчанию. При этом вы могли заметить, что положение солнца в скайбоксе, а также цвет неба изменяется соответствующим образом. Как видите, Unity 5 уже делает все, что нужно, чтобы создать смену дня и ночи. Нам остается лишь контролировать это вращение с помощью скрипта:
using UnityEngine;
using System.Collections;
public class DayNightController : MonoBehaviour {
public Light sun;
public float secondsInFullDay = 120f;
[Range(0,1)]
public float currentTimeOfDay = 0;
[HideInInspector]
public float timeMultiplier = 1f;
float sunInitialIntensity;
void Start() { sunInitialIntensity = sun.intensity; }
void Update() {
UpdateSun();
currentTimeOfDay += (Time.deltaTime / secondsInFullDay) * timeMultiplier;
if (currentTimeOfDay >= 1) { currentTimeOfDay = 0; }
}
void UpdateSun() {
sun.transform.localRotation = Quaternion.Euler((currentTimeOfDay * 360f) - 90, 170, 0);
float intensityMultiplier = 1;
if (currentTimeOfDay <= 0.23f || currentTimeOfDay >= 0.75f) {
intensityMultiplier = 0;
}
else if (currentTimeOfDay <= 0.25f) {
intensityMultiplier = Mathf.Clamp01((currentTimeOfDay - 0.23f) * (1 / 0.02f));
}
else if (currentTimeOfDay >= 0.73f) {
intensityMultiplier = Mathf.Clamp01(1 - ((currentTimeOfDay - 0.73f) * (1 / 0.02f)));
}
sun.intensity = sunInitialIntensity * intensityMultiplier;
}
}
Я удалил все комментарии, чтобы текст скрипта не занимал здесь много места, но код полностью прокомментирован в папке проекта, которую вы можете скачать в конце этого урока по Unity.
Присоедините этот скрипт к игровому объекту, а затем на месте солнца разместите источник освещения. Скрипт увеличивает значение currentTimeOfDay от 0
до 1
на число секунд, которое мы указываем. Это значение определяет полные 24 часа в игре, где 0
- полночь, 0.25
соответствует восходу солнца, 0.5
- полдень, 0.75
- закат. Как видите, по умолчанию полный рабочий день и ночь занимает 120 секунд. Когда значение достигает 1
, мы сбрасываем его обратно в 0
для начала нового дня.
UpdateSun() - именно та функция, которая двигает солнце. За движение солнца по небу отвечает первая строка кода этой функции. Мы поворачиваем на солнце на 360 градусов вокруг оси X согласно текущему времени суток. Вычтем из этого 90 градусов, чтобы солнце вставало при 0.25
, а не при 0
. С этим значением гораздо проще и удобнее работать. Ось Y определяет, где конкретно на горизонте солнце будет всходить и садиться. Моей пробной игре подходит значение «170», поэтому я выбрал его. Ось вращения Z здесь не задействована.
Остальная часть метода UpdateSun() имеет дело только с интенсивностью нашего Солнца. Мы хотим, чтобы интенсивность солнца была равна 0, когда солнце ниже горизонта, чтобы оно не светило вверх из-под земли, потому что это выглядело бы очень странно. Я также добавил код для увеличения интенсивности света, когда солнце встает и уменьшение, когда солнце садится.
Но, если вы попытаетесь проделать прямо сейчас, и у вас есть какие-то объекты в вашей сцене, то вы увидите, что объекты остаются гореть даже в ночное время, даже если вы пометите их как статические. Это совсем не то, что мы хотим. Давайте исправим это. Добавьте "Reflection Probe" на сцену, установите его тип в "Real Time" и режим обновления равным "Every frame" (каждый кадр):
Теперь любой статический объект, который вы добавляете на сцену, будет правильно освещен, но динамические объекты по-прежнему не получат правильное освещение. Но мы также можем это исправить. Добавьте "Light Probe Group" на сцену. Вам не нужно изменять настройки для этой работы. Он работает в автоматическом режиме. Теперь даже динамические объекты будут должным образом освещены вашим динамическим солнцем.
Вы, возможно, захотите подправить настройки и расположение объектов, чтобы все выглядело отлично. Но все это зависит от настроек вашей сцены. Я добавил ссылки на официальную документацию для отражающих и освещающих объектов в нижней части этого учебника. Там очень много информации, изучите ее, если вы столкнулись с проблемами.
Только что мы сделали смену ночи и дня, но вы, наверное, заметили часы на изображении в верхней части этого урока. Я добавил их потому что, на мой взгляд, было бы круто в реальном времени увидеть текущее время при смене освещения. Сейчас я покажу вам, как я это сделал (код и часы также включены в папку проекта). Часы мы с вами уже делали в уроке Создание часов в Unity.
Тем не менее, часы – это всего лишь объект, похожий на обычные часы, но с другим простым скриптом внутри. Можно, да даже и нужно, смоделировать 3D-модель часов в отдельном приложении, но для этого урока я сделал их прямо в Unity, просто соединив кубы и цилиндрические фигуры воедино. Единственно важные элементы часов – это стрелки, показывающие текущее время. Нам нужно иметь возможность ссылаться на них через скрипт и они должны иметь возможность вращаться на 360 градусов вокруг оси в центре циферблата. Что касается скрипта часов, то вот он:
using UnityEngine;
public class Clock : MonoBehaviour {
public Transform hourHand;
public Transform minuteHand;
float hoursToDegrees = 360f / 12f;
float minutesToDegrees = 360f / 60f;
DayNightController controller;
void Awake() {
controller = GameObject.Find("DayNightController").GetComponent<DayNightController>();
}
void Update() {
float currentHour = 24 * controller.currentTimeOfDay;
float currentMinute = 60 * (currentHour - Mathf.Floor(currentHour));
hourHand.localRotation = Quaternion.Euler(currentHour * hoursToDegrees, 0, 0);
minuteHand.localRotation = Quaternion.Euler(currentMinute * minutesToDegrees, 0, 0);
}
}
Здесь все довольно просто. Сначала мы задаем сколько часов в сутках и сколько минут в часе. Затем мы определяем на сколько градусов нужно повернуть часовую и минутную стрелки, чтобы перейти к следующему часу/минуте. В Update() мы получаем значение переменной currentTimeOfDay (которон является числом с плавающей точкой в диапазоне от 0
до 1
) из DayNightController и умножаем на значения, которые мы вычислили, чтобы получить текущие час и минуту. Затем поворачиваем часовую и минутной стрелки циферблата в соответствии с этими значениями. Очевидно, что мы могли бы сделать здесь и секундную стрелку, но секунды проходят так быстро, что я решил заморачиваться с ними. Этот скрипт также полностью прокомментирован в архиве проекта.
Если вы внимательно изучали скрипт DayNightController вы, возможно, заметили публичную переменную timeMultiplier. С ее помощью можно менять скорость наступления дня и ночи. Я добавил небольшой скрипт для моей сцены, который позволяет мне ускорить или замедлить время, используя клавиши W
и S
или ↑
и ↓
. Также я добавил элемент Bloom, чтобы это выглядело новее и добавил некое количество твёрдых сферических тел, чтобы показать, что с динамическими движущимися объектами всё работает отлично. Излучающиеся части часов также показывают, как классно выглядит освещение в Unity 5
Вы можете посмортеть, что мы сотворили в Unity web-плеере или скачать всю папку проекта.
Здесь находится официальная документация о Reflection Probes, а на этой странице вы можете почитать о группе световых зондов.