Владимир Шека 4 Share Posted August 20, 2019 В этой теме публикуются интересные и полезные функции UI скриптов в Unity (Unity3d). UI - User Interface. Quote Link to post Share on other sites
Владимир Шека 4 Author Share Posted August 20, 2019 Как сделать, чтобы в 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-элемент в Юнити, и теперь при перетягивании его мышкой он будет менять свое положение на экране. Quote Link to post Share on other sites
Владимир Шека 4 Author Share Posted August 20, 2019 Дочерние окна тоже цепляются мышкой, что делать? Перетаскивание окон в Юнити можно сделать круче и исправить некоторые недостатки, что есть в движке. Например, если сделать у окна лишь определенную зону, за которую можно цепляться (например, заголовок окна), и у этой зоны сделать дочерним объект (любой элемент, например, 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 вышло за пределы экрана, как вернуть назад? Вышеописанный скрипт также содержит метод, который возвращает в зону разрешения экрана окно, если оно вышло за пределы координат. Срабатывает проверка автоматически при завершении перетаскивания. Quote Link to post Share on other sites
Владимир Шека 4 Author Share Posted August 20, 2019 Как масштабировать UI в Юнити под разрешение экрана? В Canvas необходимо выбрать режим Scale With Screen Size. На любом канвасе автоматически есть компонент Canvas Scaler, режим выставляется там. После этого все дочерние элементы пользовательского интерфейса будут уменьшаться пропорционально Y-разрешению экрана. В самих элементах, возможно, нужно будет поколдовать с RectTransform, точно не помню, вроде что-то с Pivot и привязкой (попробуйте привязать изначально к верху середины). Quote Link to post Share on other sites
Владимир Шека 4 Author Share Posted August 20, 2019 Видеоуроки по UI в Unity: Динамический список со скроллом. Unity3d UI (ScrollView Adapter) Перемещение UI объектов мышкой Quote Link to post Share on other sites
Владимир Шека 4 Author Share Posted August 26, 2019 Как изменить позицию 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; } Quote Link to post Share on other sites
Владимир Шека 4 Author Share Posted August 27, 2019 Не позволяет окнам выходить за разрешение экрана Алгоритм не самый удачный, но сохраню это здесь, вдруг приходится. //сколько пикселей от конца экрана безопасная зона, куда будет возвращено окно //при перетаскивании за край экрана 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); } } Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.