Jump to content

Unity: UI шпаргалка по скриптам интерфейса


Recommended Posts

 

Как сделать, чтобы в Unity окно можно было перетаскивать?

 

Перетаскивание окон. Это работает не только с окнами, но и любыми элементами интерфейса (UI). Нужно просто реализовать интерфейс (термин из C#) и событие. Вот самый простой пример:

Спойлер

 


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; //обязательно для работы с системой событий

public class TestDrag : MonoBehaviour, IDragHandler //интерфейсы
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // в процессе перетаскивания
    public void OnDrag(PointerEventData eventData)
    {
        // окно движется вместе с мышкой
        transform.position = Input.mousePosition;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

 

Вешаете этот скрипт на UI-элемент в Юнити, и теперь при перетягивании его мышкой он будет менять свое положение на экране.

Link to post
Share on other sites
 

Дочерние окна тоже цепляются мышкой, что делать?

 

Перетаскивание окон в Юнити можно сделать круче и исправить некоторые недостатки, что есть в движке. Например, если сделать у окна лишь определенную зону, за которую можно цепляться (например, заголовок окна), и у этой зоны сделать дочерним объект (любой элемент, например, Panel), то панель тоже будет цепляться курсором, что далеко не всегда нужно. Исправляется это так:

Задача: сделать так, чтобы только один элемент (заголовок) был зоной для перетаскивания, а его дочерние UI-элементы нет. Решение: вешаем этот скрипт на нужный элемент для перетаскивания, а также на тот, который перетаскивать не надо (он будет перетаскиваться вместе с родительским (заголовком)), но у дочернего убираем галочку на isDragging:
 

Спойлер

 


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems; //обязательно для работы с системой событий

public class Window : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler //интерфейсы
{

    //стартовая позиция мыши при начале перетаскивания
    //нужна, чтобы окно сразу не дергалось центрируясь по курсору мышки
    //а плавно меняла положение вслед за курсором
    private Vector3 mouseStartingPos;

    //поддается ли перетаскиванию (цепляет ли его курсор)
    public bool isDragging = true;

    //сколько пикселей от конца экрана безопасная зона, куда будет возвращено окно
    //при перетаскивании за край экрана
    int pixeSafeZone = 20;

    //начало перетаскивания
    public void OnBeginDrag(PointerEventData eventData)
    {
        //запоминаем где была мыш на начале перетаскивания
        mouseStartingPos = Input.mousePosition;
    }

    // в процессе перетаскивания (вызывается каждый раз при изменении положении мышки)
    public void OnDrag(PointerEventData eventData)
    {
        //если окно может цеплять курсор (перетаскиваемое)
        if (isDragging)
        { 
        //позиция окна изменяется соответственно тому, как изменилась
        //позиция мышки в процессе перетаскивания. При каждом движении вычисляем
        //разницу между прошлым и текущим положением мышки и применяем ее к окну
        transform.position -= mouseStartingPos - Input.mousePosition;
        //запоминаем текущее положение
        mouseStartingPos = Input.mousePosition;
        }
    }



    //в конце перетаскивания
    public void OnEndDrag(PointerEventData eventData)
    {
        //не позволить окнам выходить за разрешение экрана
        CheckOutScreen();

    }

    //не позволяет окнам выходить за разрешение экрана
    private void CheckOutScreen ()
    {
        //если окно вышло по иску за пределы экрана вправо
        if (transform.position.x > Screen.width)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(Screen.width - pixeSafeZone, transform.position.y);
        }
        //если окно вышло по иску за пределы экрана влево
        else if (transform.position.x <= 0)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(pixeSafeZone, transform.position.y);
        }

        //если окно вышло по игреку за пределы экрана вправо
        if (transform.position.y > Screen.height)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(transform.position.x, Screen.height - pixeSafeZone);
        }
        //если окно вышло по игреку за пределы экрана влево
        else if (transform.position.y <= 0)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(transform.position.x, pixeSafeZone);
        }
    }

    void Update()
    {

    }

    void Start()
    {
    }
}

 

 

 

 

Окно в Unity вышло за пределы экрана, как вернуть назад?


Вышеописанный скрипт также содержит метод, который возвращает в зону разрешения экрана окно, если оно вышло за пределы координат. Срабатывает проверка автоматически при завершении перетаскивания.

Link to post
Share on other sites
 

Как масштабировать UI в Юнити под разрешение экрана?

 

В Canvas необходимо выбрать режим Scale With Screen Size. На любом канвасе автоматически есть компонент Canvas Scaler, режим выставляется там. После этого все дочерние элементы пользовательского интерфейса будут уменьшаться пропорционально Y-разрешению экрана. В самих элементах, возможно, нужно будет поколдовать с RectTransform, точно не помню, вроде что-то с Pivot и привязкой (попробуйте привязать изначально к верху середины).

Link to post
Share on other sites
 
 

Как изменить позицию UI-элемента (окна, кнопки т.п.) в Юнити?

 

gameObject.transform.position = new Vector2(transform.position.x + 190, transform.position.y);

Пример кода, который по иксу двигает элемент пользовательского интерфейса на 190 пикселей. Y остается таким же (так как туда вводится та же координата, которой Y сейчас соответствует).

Но при смене разрешения такой подход может привести к тому, что элемент окажется за экраном, так как это позиция в пикселях.

 

Второй способ перетаскивания в UI

 

Есть второй способ, который считывает движение мыши (я так понимаю мыши передает лишь +1 либо -1), но окно движется очень медленно и ускорение мышки влияет так, что окно отстает:

transform.position += new Vector3(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));

Нормальный способ перетащить окно в Unity

 

А вот это похоже на что-то вменяемое, нужно реализовать интерфейс (ищите инфу что за интерфейсы по началу перетаскивания, в процессе и в конце):

public void OnDrag(PointerEventData eventData)
    {
        transform.position += (Vector3)eventData.delta;
    }

 

Link to post
Share on other sites
 

Не позволяет окнам выходить за разрешение экрана

Алгоритм не самый удачный, но сохраню это здесь, вдруг приходится.

    //сколько пикселей от конца экрана безопасная зона, куда будет возвращено окно
    //при перетаскивании за край экрана
    int pixeSafeZone = 35;

//скрипт должен быть на объекте, и вызываться должна эта функция дял проверки выхода за экран
private void CheckOutScreen()
    {
        #region //не позволяет окнам выходить за разрешение экрана
        //если окно вышло по иску за пределы экрана вправо
        if (transform.position.x > Screen.width)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(Screen.width - pixeSafeZone, transform.position.y);
        }
        //если окно вышло по иску за пределы экрана влево
        else if (transform.position.x <= 0)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(pixeSafeZone, transform.position.y);
        }

        //если окно вышло по игреку за пределы экрана вверх
        if (transform.position.y > Screen.height)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(transform.position.x, Screen.height - pixeSafeZone);
        }
        //если окно вышло по игреку за пределы экрана вниз
        else if (transform.position.y <= 0)
        {
            //возвращаем его в пределы экрана
            transform.position = new Vector3(transform.position.x, pixeSafeZone);
        }
    }

 

Link to post
Share on other sites
 

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Powered by Invision Community
Поддержка Invision Community в России

×
  • Create New...