UNITY В режиме прокрутки, как мне перетаскивать, когда я нажимаю на дочерние элементы?

Рассмотрим следующую настройку: у меня есть 2D-массив, использующий вертикальную и вертикальную группу макетов Scrollviewrect. А затем в сторону дочерней группы горизонтального макета.

Обновлено: Это происходит, когда я запускаю игру, а не в редакторе.

EDIT2: значки карты — это кнопки. Я пробовал удалить сценарий кнопки, но он все тот же.

Моя проблема в том, что я могу перетаскивать его вверх и вниз, только если нажимаю между значками, но когда я нажимаю на значки, он не перетаскивается.

Это потому, что в моем значке реализовано событие щелчка, которое блокирует событие перетаскивания? Как это исправить?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
144
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не можете их перетаскивать, потому что на них влияет группа макетов, вот... для чего она создана. Чтобы изменить расположение «значков карты», достаточно изменить размеры объекта «Содержимое» или изменить значения в группе вертикальной компоновки.

Похоже, мой вопрос сбивает с толку, я добавлю некоторые пояснения. Я имел в виду, что когда я запускаю игру, я могу перетаскивать вид прокрутки, но если я нажимаю на «значки карты», он не перемещается, мне приходится щелкать между значками, чтобы перетащить прокрутку.

Airborne STD 10.05.2024 10:18

Могу ли я спросить, какую версию Unity вы используете? У меня был такой случай в старых версиях, но это было очень давно.

TheQuaX 10.05.2024 11:02

2022.3.4f1, возможно, это произошло из-за того, что событие значка блокирует событие прокрутки, попробую сегодня вечером

Airborne STD 10.05.2024 15:35

Как вы упомянули, событие щелчка на вашем MapIcon может блокировать событие прокрутки. Чтобы это исправить, вы можете использовать EventTrigger Unity для проверки событий щелчка и перетаскивания. Запустите таймер в PointerDown, а затем проверьте в PointerUp, меньше ли прошедшее время порогового значения. Если оно меньше, это событие щелчка, иначе — событие перетаскивания.

Что-то вроде:

using UnityEngine;
using UnityEngine.EventSystems;

public class MapIconClickHandler : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    private bool isDragging;
    private float timePointerDown;
    public float clickTime = 0.2f; // Maximum time until a pointerdown/up is considered a click

    public void OnPointerDown(PointerEventData eventData)
    {
        timePointerDown = Time.time;
        isDragging = false;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        if (Time.time - timePointerDown > clickTime)
            isDragging = true;

        if (!isDragging)
        {
            // Handle Click event
            Debug.Log("ClickEvent");
        }
        else
        {
            // Handle Drag event
            Debug.Log("DragEvent");
        }
    }
}

Редактировать:

Если вам нужны кнопки, оставьте свой скрипт для кнопок и просто добавьте следующее в свой MapIconButton:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class DragHandler : MonoBehaviour, IDragHandler
{
    public ScrollRect scrollRect;

    public void OnDrag(PointerEventData eventData)
    {
        // calculate mouse y position delta 
        float delta = eventData.delta.y;

        // update vertikaleNormalizedPosition based on mouse movement
        scrollRect.verticalNormalizedPosition += delta * Time.deltaTime;
    }
}

Вы можете поиграть с нормализацией ввода с помощью мыши, но для простоты этого шаблона должно быть достаточно.

Что, если значки на карте — это кнопки? Я попытался удалить сценарий кнопки из значков, но их все равно нельзя перетащить. Должен ли я попробовать передать событие на нижний уровень? Не знаю, как это сделать...

Airborne STD 10.05.2024 19:09

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

TheQuaX 13.05.2024 07:52
Ответ принят как подходящий

Решение близко к тому, что есть у TheQuaX, но я нашел лучший способ — передать событие прокрутке.

Вот код, который я нашел на форуме Unity.

https://forum.unity.com/threads/child-objects-blocking-scrollrect-from-scrolling.311555/

public class FixScrollRect: MonoBehaviour, IBeginDragHandler,  IDragHandler, IEndDragHandler, IScrollHandler
{
    public ScrollRect MainScroll;
 
 
    public void OnBeginDrag(PointerEventData eventData)
    {
        MainScroll.OnBeginDrag(eventData);
    }
 
 
    public void OnDrag(PointerEventData eventData)
    {
        MainScroll.OnDrag(eventData);
    }
 
    public void OnEndDrag(PointerEventData eventData)
    {
        MainScroll.OnEndDrag(eventData);
    }
 
 
    public void OnScroll(PointerEventData data)
    {
        MainScroll.OnScroll(data);
    }
 
 
}

Другие вопросы по теме