Меню привязки клавиш + сохранение

Простой пример меню привязки клавиш с функцией сохранения и загрузки настроек. Принцип работы в следующем. Каждая опция привязки, это обычная UI кнопка, ее в свою очередь мы настраиваем с помощью специального класса, то есть, там прописывается ключ вызова и кей-код к нему. Поскольку коды клавиш мы можем менять на какие угодно, то ключ всегда остается неизменным, и именно к нему обращаемся, чтобы проверить нажатие клавиши. Переназначение клавиши делается очень просто, достаточно кликнуть по нужной кнопке, после скрипт переходит в режим ожидания, как только игрок нажмет какую-нибудь клавишу, она сразу назначается данному классу.

Меню привязки клавиш + сохранение

Итак, на кнопку вешаем:

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

public class InputComponent : MonoBehaviour {

	[SerializeField] private Text _buttonText; // текст кнопки
	[SerializeField] private string _defaultKeyName; // ключ/имя вызова
	[SerializeField] private KeyCode _defaultKeyCode; // клавиша ключа

	public KeyCode keyCode { get; set; }

	private IEnumerator coroutine;
	private string tmpKey;

	public Text buttonText
	{
		get{ return _buttonText; }
	}

	public string defaultKeyName
	{
		get{ return _defaultKeyName; }
	}
	
	public KeyCode defaultKeyCode
	{
		get{ return _defaultKeyCode; }
	}

	public void ButtonSetKey() // событие кнопки, для перехода в режим ожидания
	{
		tmpKey = _buttonText.text;
		_buttonText.text = "???";
		coroutine = Wait();
		StartCoroutine(coroutine);
	}

	// ждем, когда игрок нажмет какую-нибудь клавишу, для привязки
	// если будет нажата клавиша 'Escape', то отмена
	IEnumerator Wait()
	{
		while(true)
		{
			yield return null;

			if(Input.GetKeyDown(KeyCode.Escape))
			{
				_buttonText.text = tmpKey;
				StopCoroutine(coroutine);
			}

			foreach(KeyCode k in KeyCode.GetValues(typeof(KeyCode)))
			{
				if(Input.GetKeyDown(k) && !Input.GetKeyDown(KeyCode.Escape))
				{
					keyCode = k;
					_buttonText.text = k.ToString();
					StopCoroutine(coroutine);
				}
			}
		}
	}
}

И настраиваем параметры по умолчанию, ключ вызова и кей-код.

Меню привязки клавиш + сохранение

Кроме того не забываем добавить событие кнопки.

Теперь, добавляем на сцену:

using UnityEngine;
using System.Collections;
using System.IO;

public class GameInput : MonoBehaviour {

	[SerializeField] private string fileName = "input.settings"; // имя файла сохранения с разрешением
	[SerializeField] private InputComponent[] _input; // массив кнопок

	private static GameInput gameInput;

	public static GameInput Key
	{
		get{ return gameInput; }
	}

	void Awake()
	{
		gameInput = this;
	}

	KeyCode FindKey(string name) // поиск кей-кода по имени
	{
		for(int i = 0; i < _input.Length; i++)
		{
			if(name == _input[i].defaultKeyName) return _input[i].keyCode;
		}

		return KeyCode.None;
	}

	int GetInt(string text)
	{
		int value;
		if(int.TryParse(text, out value)) return value;
		return 0;
	}

	string Path() // путь сохранения
	{
		return Application.dataPath + "/" + fileName;
	}

	void SetKey(string value) // настройка кнопок
	{
		string[] result = value.Split(new char[]{'='});

		for(int i = 0; i < _input.Length; i++)
		{
			if(result[0] == _input[i].defaultKeyName)
			{
				_input[i].keyCode = (KeyCode)GetInt(result[1]);
				_input[i].buttonText.text = _input[i].keyCode.ToString();
			}
		}
	}

	public void DefaultSettings() // возврат настроек по умолчанию
	{
		for(int i = 0; i < _input.Length; i++)
		{
			_input[i].keyCode = _input[i].defaultKeyCode;
			_input[i].buttonText.text = _input[i].defaultKeyCode.ToString();
		}
	}

	public void LoadSettings() // загрузка установок
	{
		if(!File.Exists(Path()))
		{
			DefaultSettings();
			return;
		}

		StreamReader reader = new StreamReader(Path());

		while(!reader.EndOfStream)
		{
			SetKey(reader.ReadLine());
		}

		reader.Close();
	}

	public void SaveSettings()
	{
		StreamWriter writer = new StreamWriter(Path());

		for(int i = 0; i < _input.Length; i++)
		{
			writer.WriteLine(_input[i].defaultKeyName + "=" + (int)_input[i].keyCode);
		}

		writer.Close();
		Debug.Log(this + " сохранения настроек привязки клавиш: " + Path());
	}

	public bool GetKey(string name)
	{
		return Input.GetKey(FindKey(name));
	}

	public bool GetKeyDown(string name)
	{
		return Input.GetKeyDown(FindKey(name));
	}

	public bool GetKeyUp(string name)
	{
		return Input.GetKeyUp(FindKey(name));
	}
}

Заполняем массив, кнопками на которых мы настроили InputComponent. И готово.

Настройки имеет смысл загружать при запуске игры, а не каждой сцены. То бишь всё игровое меню настроек, графики и прочего можно повесить на один объект с использованием функции DontDestroyonload, менюшка будет загружаться один раз и присутствовать на всех сценах. Остается только, включать и выключать ее, по необходимости.

Конкретно в данном случаи загрузка запускается так:

void Start()
{
	GameInput.Key.LoadSettings();
}


Использование ключей:

void Update()
{
	if(GameInput.Key.GetKey("MyKeyName"))
	{
		// клавиша удерживается
	}

	if(GameInput.Key.GetKeyDown("MyKeyName"))
	{
		// клавиша нажата
	}

	if(GameInput.Key.GetKeyUp("MyKeyName"))
	{
		// клавиша отпущена
	}
}

В общем, всё просто.

Скачать демку:

У вас нет доступа!
Тестировалось на: Unity 5.3.6
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика