- PVSM.RU - https://www.pvsm.ru -
Приветствую!
Я знаю, и вы в глубине души знаете, чего не хватает вашим карточным играм или играм «три в ряд». Системы скрытности!
И конечно же, любая уважающая себя система скрытности должна уметь принимать в расчет освещенность окружения вокруг игрока. Я был изумлен, раскопав тему и обнаружив аномально малое количество инфы. Поэтому спешу поделиться плодами.
Сегодня мы не будем разрабатывать полноценную систему скрытности для игрока, рассмотрим чисто взаимодействия с освещением.
Простой и не особо ресурсоёмкий способ.
К каждому источнику освещения добавляем по сферическому коллайдеру. Делаем его триггером. Выставляем размеры примерно равными радиусу света.
Остальное — ясно, как тень. Пишем простенький скрипт, где в OnTriggerEnter() размещаем активацию расчета освещенности (чтобы источники света не работали «вхолостую», когда игрока рядом нет).
Сам расчет освещенности будет расположен в Update(). По сути, это обычный Physics.Raycast(). Если попадает в игрока — игрок в зоне света. Если не попадает — значит, игрок за препятствиями и, значит, в тени.
Также сюда можно дописать расчет расстояния между игроком и источником света. Таким образом, для определения освещенности у нас будет служить простенький float, который будет меняться в зависимости от расстояния до источников света. А использовать его можно где душа пожелает.
И это не всё! Можно добавить триггер-коллайдеров в различные «зоны теней», где игрок должен прятаться. В лучших традициях Manhunt. Аналогичным образом можно помечать коллайдером светлые зоны, имитируя, например, свет прожектора.
Что мы тут делаем? По сути — получаем «скриншот» с камеры, причем необязательно с камеры основной. А затем анализируем цвет скриншота, чтобы узнать, насколько яркий свет падает на предмет.
Для начала нам нужен объект, с которого мы будем «читать» свет. Создаем обычную сферу или плоскость, делаем маленькой (scale 0.1), размещаем вплотную к полу, делаем белой, убираем коллайдер:
Добавляем камеру (обязательно убираем audio listener и проверяем, что не стоит таг MainCamera). Привязываем её к нашему объекту. Ставим её чуть выше, направляем вниз. Выставляем в настройках не основной дисплей. Делать ли её ортографической — это на ваш вкус.
Под конец позиционируем её так, чтобы она смотрела на наш объект и только на него.
Под конец настраиваем Culling mask основной и вторичных камер, чтобы основная не отображала наши «световые» объекты, а вторичные видели только их, не захламляясь ничем прочим.
И тут начинается самое интересное. Привязываем к камере скрипт:
public Camera cam; // наша камера
RenderTexture tex;
Texture2D _tex;
void Start () {
// Создаем изображение для "скриншота".
// Да, он всего в один пиксель размером - больше не надо.
// Depth лучше на 0 не ставить - появляются различные баги.
tex = new RenderTexture (1, 1, 8);
// RenderTexture "читать" нельзя,
// поэтому создаем текстуру, в которую его переводим.
_tex = new Texture2D (1, 1, TextureFormat.RGB24, false);
}
void Update () {
// назначаем текстуру "скриншота" камере
cam.targetTexture = tex;
cam.Render ();
// делаем полученный скриншот активным
RenderTexture.active = tex;
// записываем в Texture2D
_tex.ReadPixels (new Rect (0, 0, 1, 1), 0, 0);
_tex.Apply ();
Color col = _tex.GetPixel (0, 0);
float vis = (col.r + col.g + col.b) / 3;
}
На выходе получаем float vis, который, по сути, является числовой репрезентацией уровня освещения, падающего на наш объект. Если источник близко — предмет белый — vis равен 1. Если темно — предмет черный — vis равен ~0.
Нам не нужно проделывать вышеуказанную операцию каждый фрейм, так что встраиваем небольшой секундный таймер:
float interval = 0;
void Update ()
{
interval += Time.deltaTime;
if (interval < 1)
return;
interval = 0;
// наш код
}
Далее мы всю нашу систему привязываем к игроку, чтобы она передвигалась вместе с ним. И наша переменная vis автоматически выдает освещенность вокруг игрока!
Данную систему можно использовать не только в связке с игроком. Можно разместить её где угодно и как угодно, создавая своеобразные датчики света. Как правило для их реализации имеются более эффективные пути, но всегда приятно иметь альтернативы?
Преимущества очевидны, поговорим о недостатках.
Автор: Xatmo
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/unity3d/285950
Ссылки в тексте:
[1] Источник: https://habr.com/post/417135/?utm_campaign=417135
Нажмите здесь для печати.