Как сделать джойстик в Unity 5

В этом уроке мы разберем, как сделать джойстик в Unity 5, работающий на всех платформах, включая Android и IOS. Для начала имеем: пустой проект и Canvas на нем. Если вы не знаете, что такое Canvas, или не разобрались в нем (например, не знаете как сделать масштабируемость интерфейса), то рекомендую посмотреть урок по созданию главного меню для того, чтоб лучше в этом разобраться.

Canvas мы переименуем как MobileInputCanvas и создадим на нем Image, который назовем JoystickHolder, выберем ему необходимый размер (изменив width и height свойства), а так же поставим его в нужное место. В Image мы выберем нужный спрайт, если у вас есть заготовки для спрайтов под джойстик и место, где от будет кататься, а если нет, то можете выбрать уже готовый круг. Для этого необходимо выбрать нужный нам объект Image и выбрать св-во Source Image. Далее в Unity уже есть картинка Knob, нужно выбрать именно её. Следующим мы создадим в JoystickHolder еще один Image, который назовем Joystick и проделаем с ним те же действия, но поменяем ему размер на более меньший. А так же нужно перекрасить наши круги в необходимые для вас цвета. В конце этих действий получиться что-то похожее на это:

Реализация joystick для Unity3d

Теперь необходимо написать статический класс, который будет хранить в себе все значения из нашего джойстика. Для этого создадим класс 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 закончен.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (3 оценок, среднее: 5,00 из 5)
Adblock
detector