Как сделать джойстик в Unity 5
В этом уроке мы разберем, как сделать джойстик в Unity 5, работающий на всех платформах, включая Android и IOS. Для начала имеем: пустой проект и Canvas на нем. Если вы не знаете, что такое Canvas, или не разобрались в нем (например, не знаете как сделать масштабируемость интерфейса), то рекомендую посмотреть урок по созданию главного меню для того, чтоб лучше в этом разобраться.
Canvas мы переименуем как MobileInputCanvas и создадим на нем Image, который назовем JoystickHolder, выберем ему необходимый размер (изменив width и height свойства), а так же поставим его в нужное место. В Image мы выберем нужный спрайт, если у вас есть заготовки для спрайтов под джойстик и место, где от будет кататься, а если нет, то можете выбрать уже готовый круг. Для этого необходимо выбрать нужный нам объект Image и выбрать св-во Source Image. Далее в Unity уже есть картинка Knob, нужно выбрать именно её. Следующим мы создадим в JoystickHolder еще один Image, который назовем Joystick и проделаем с ним те же действия, но поменяем ему размер на более меньший. А так же нужно перекрасить наши круги в необходимые для вас цвета. В конце этих действий получиться что-то похожее на это:
Теперь необходимо написать статический класс, который будет хранить в себе все значения из нашего джойстика. Для этого создадим класс AndroinIosInput и напишем в нем:
//Делаем класс статическим, чтобы его элементы были доступны из любого места public static class AndroidIosInput { //Словарь для того, чтоб хранить данные о джойстике по его имени static Dictionary<string, Vector2> JoySticks; static AndroidIosInput() { //при загрузке этого класса, мы создаем новый словарь JoySticks = new Dictionary<string, Vector2>(); } //Метод регистрации. Когда джойстик появляется, он регистрируется public static void RegisterJoystick(string Name) { //Проверяем этот джойстик на наличие if (JoySticks.ContainsKey(Name)) throw new System.Exception("Joystick " + Name + " already registered"); //Если его нет, то регистрируем наш джойстик JoySticks.Add(Name, Vector2.zero); } //Получение значения джойстика public static Vector2 GetJoystickValue(string Name) { //Проверяем его наличие if (!JoySticks.ContainsKey(Name)) throw new System.Exception("Joystick " + Name + " didn't registered"); //Возвращаем значение джойстика, если он есть return JoySticks[Name]; } //Установление значения джойстика public static void SetJoystickValue(string Name, Vector2 Value) { if (!JoySticks.ContainsKey(Name)) throw new System.Exception("Joystick " + Name + " didn't registered"); //Устанавливаем значение для джойстика JoySticks[Name] = Value; } //Удаление джойстика public static void RemoveJoystick(string Name) { JoySticks.Remove(Name); } }
Далее создадим класс JoystickController, который мы повесим на наш Joystick Holder, чтобы тот начал передавать значения в наш статический класс.
public class JoystickController : MonoBehaviour, IDragHandler, IEndDragHandler { //Радиус, на который будет двигаться джойстик public float Range = 10; //Название джойстика public string StickName; //место, где появился джойстик(чтоб считать радиус Vector2 _startPosition; //делаем локальную переменную для нашего джойстика //чтоб постоянно не обращаться к нему через //transform.GetChild(0); Transform _joystickTransform; void Start() { //В начале работы необходимо зарегестрировать джойстик AndroidIosInput.RegisterJoystick(StickName); //Запоминаем изначальное положение джойстика _startPosition = transform.GetChild(0).position; //Запоминаем джойстик в локальной переменной _joystickTransform = transform.GetChild(0); } //Метод, который срабатывает, когда объект пытаются двигать public void OnDrag(PointerEventData Data) { //Ппроверяем расстояние до точки, куда джойстик пытаются перетащить if (Vector2.Distance(_startPosition, Data.position) < Range) { //Если расстояние приемлимое, то переносим наш джойстик туда, где сейчас палец _joystickTransform.position = Data.position; //и заносим данные о джойстике в наш класс //где (Data.position.x - _startPosition.x) / Range - значение от -1 до 1 AndroidIosInput.SetJoystickValue(StickName, new Vector2((Data.position.x - _startPosition.x) / Range, (Data.position.y - _startPosition.y) / Range)); } else { //запоминаем смещение по x и y от начала float deltaX = Data.position.x - _startPosition.x; float deltaY = Data.position.y - _startPosition.y; //Ищем точку на тригонометрической окружности относительно смещения //И чтоб была на краю нашего Range Vector2 state = Vector2.ClampMagnitude(new Vector2(deltaX, deltaY), Range); //перемещаем джойстик в эту точку _joystickTransform.position = state + _startPosition; //Устанавливаем значение джойстика //где state.x / Range - значение от -1 до 1 AndroidIosInput.SetJoystickValue(StickName, new Vector2(state.x / Range, state.y / Range)); } } public void OnEndDrag(PointerEventData Data) { //Обнуляем наш джойстик AndroidIosInput.SetJoystickValue(StickName, Vector2.zero); //Возвращаем его на прежнее место _joystickTransform.position = _startPosition; } private void OnDestroy() { //Удаляем запись о джойстике в случае смены сцены или удаления джойстика AndroidIosInput.RegisterJoystick(StickName); } }
Стоит разобраться с тем что такое IDragHandler и IEndDragHandler, это интерфейсы, которые вызываются при соответствующем событии отностительно курсора. Например, IDragHandler вызывается, когда курсор двигается, а IEndDragHandler когда передвижение заканчивается. Все эти интерфейсы находятся в области имен UnityEngine.EventSystems.
В итоге при нажатии и движении в области джойстика, джойстик автоматически переходит под палец и мы начинаем им управлять, изменяя значения в статическом классе. На этом разбор того, как сделать джойстик в Unity 5 закончен.