Делаем фонарик и управление им

Итак, будем делать фонарик для нашего ужастика или может шутера, не суть. Вообще, даже для тех только начинает изучать Unity, такая вещь должна быть очевидна. Просто добавляешь источник света и вроде бы всё готово. Но здесь мы реализуем полноценное управление фонариком. То есть, вкл./выкл. плюс перезарядка, также у нашего фонарика будет конкретное количество, как бы запасных батареек. Дополнительно сделаем индикатор, который будет отображать текущий заряд батареи. Когда заряд падает, индикатор изменит цвет, а если батарея почти разрядилась, то с начала падает яркость, затем начинается мерцание и фонарик гаснет.


Приступим. Добавляем на сцену Spotlight, ставим источник света в нужное место, настраиваем основные параметры: цвет, дальность, угол. Включаем тени, если нужно и еще нам надо сделать печеньку Cookie, то есть это текстура для света, наложение узора.

Делаем фонарик и управление им

Текстура должна иметь примерно такой вид:


Настройки импортирования для этой текстуры:


Далее, чтобы сделать индикатор, добавляем на сцену UI > Slider и настраиваем его визуально.

Когда всё готово, вешаем в удобное место скрипт управление Flashlight:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Flashlight : MonoBehaviour {

	public KeyCode control = KeyCode.F; // клавиша управления фонариком, вкл/выкл и перезарядка
	public float timeout = 30; // время работы фонарика в секундах

	public Light _light; // источник света

	// минимальная и максимальная интенсивность источника света
	public float min = 1;
	public float max = 8;
	
	public Slider slider; // элемент UI

	// цвета индикатора
	public Color maxColor = Color.white;
	public Color halfColor = Color.yellow;
	public Color minColor = Color.red;

	public float reloadTime = 2.5f; // время перезарядки в секундах
	public int batteryCount = 3; // доступное количество запасных батареек

	private float curTime;
	private Image sliderColor;
	private float curReloadTime;

	void Awake () 
	{
		sliderColor = slider.fillRect.GetComponentInChildren<Image>();
	}

	void Start () 
	{
		sliderColor.color = maxColor;
		slider.minValue = 0;
		slider.maxValue = 100;
		slider.value = 100;
		_light.enabled = false;
		_light.intensity = min;
	}

	void Update () 
	{
		if(Input.GetKeyDown(control) && !_light.enabled && slider.value > 1)
		{
			_light.enabled = true;
		}
		else if(Input.GetKeyDown(control) && _light.enabled)
		{
			_light.enabled = false;
			_light.intensity = min;
		}

		if(_light.enabled)
		{
			curTime += Time.deltaTime;

			if(curTime > timeout) 
			{
				curTime = 0;
				slider.value = 0;
				_light.enabled = false;
			}
			else if(curTime != 0)
			{
				// переводим время в диапазон значений от 0 до 100% и вычетам из 100
				slider.value = 100 - (curTime/timeout) * 100;
			}

			float intensity = max;
			Color curColor = maxColor;

			if(slider.value < 50) curColor = halfColor; // меняем цвет на промежуточный, если меньше 50% заряда

			if(slider.value < 20) 
			{
				curColor = minColor;
				intensity = max / 2; // снижаем яркость фонарика

				if(Random.Range(0, 0.9f) > 0.5f) intensity = intensity / Random.Range(1, 6); // рандомное мерцание, перед отключением
			}

			sliderColor.color = Color.Lerp(sliderColor.color, curColor, 1.5f * Time.deltaTime);
			_light.intensity = Mathf.Lerp(_light.intensity, intensity, 3f * Time.deltaTime);
		}
		else if(Input.GetKey(control) && slider.value < 90 && batteryCount > 0) // перезарядка, если заряда батареи меньше 90% и есть еще запасные
		{
			curReloadTime += Time.deltaTime;
			if(curReloadTime > reloadTime) 
			{
				curReloadTime = 0;
				batteryCount--;
				sliderColor.color = maxColor;
				slider.value = 100;
				_light.intensity = min;
			}
		}
		else
		{
			curReloadTime = 0;
		}
	}
}

Вот и вся история. Для включения и выключения - клик по клавише, а чтобы перезарядить фонарик, нужно удерживать клавишу.

Скачать демо сцену:

Внимание! Посетители, находящиеся в группе Гости, не могут скачивать файлы.

Комментариев 5

Офлайн
Супер! Спасибо большое.))
Офлайн
masyaa 5 апреля 2018
Здравствуйте. Вы когда с таким фонариком подходите в упор к стене , то луч сужается и пропадает, а как сделать так, чтоб угол постепенно увеличивался при приближении и не сужался? т.е. чтобы если стоишь в упор к стене освещение от фонаря было, а не пропадало.
Офлайн
Light 5 апреля 2018
masyaa, ну вообще то он и должен сужаться, но если надо сделать угол фонарика шире, то просто у источника света Light отрегулировать параметр Spot Angle.
Офлайн
masyaa 6 апреля 2018
Light,да, я понимаю. но допустим меня устраивает угол в 60 градусов. ну согласитесь, что если у вас в том же хороре будет фонарь с огромным лучом, то будет менее органично все смотреться. я пытался сделать так, что если расстояние меньше двух(через рейкасты) то увеличиваем SpotAngle , но он резко увеличивается. как можно было бы сделать некое постепенное увлечение?
Офлайн
Light 6 апреля 2018
masyaa, плавно менять угол переменной _light, можно так:

_light.spotAngle = Mathf.Lerp(_light.spotAngle, value, speed * Time.deltaTime);
Где value целевой угол. А speed скорость (плавность).
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика