Как реагировать только на прикосновения в изображении пользовательского интерфейса? - PullRequest
0 голосов
/ 01 марта 2019

Я ломал голову и использовал каждую поисковую фразу Google, которую только мог придумать, и пока не нашел решения.

У меня есть приложение Unity с 3D-сценой и элементами пользовательского интерфейса, которые плавают над ней.Существует один элемент пользовательского интерфейса, который представляет собой изображение транспортира.Это изображение должно быть наркотиком вокруг сцены, повернуто и масштабировано.Все это работает, единственная проблема в том, что не имеет значения, если пользователь касается транспортира или где-то еще, транспортир всегда реагирует.

Я начал с того, что искал что-то вроде someCGRect.contains(someCGPoint) Свифта, чтобы мог игнорировать все, что находится за пределами транспортира.У изображения, похоже, нет такого свойства, поэтому я провел много других поисков.

Я наконец нашел это видео;https://www.youtube.com/watch?v=sXc8baUK3iY, который в основном имеет то, что я ищу ... Кроме того, не работает.

Видео использует коллайдер и твердое тело, а затем в проверках кода, чтобы увидеть, перекрывает ли коллайдер касаниеточка.Похоже, именно то, что мне нужно.К сожалению, никакие прикосновения никогда не перекрываются с коллайдером, где бы они ни находились.После некоторого Debug.Log я обнаружил, что экстенты коллайдера сообщаются как (0, 0, 0).Именно поэтому ни одно из прикосновений не перекрывается с ним, но я не могу понять, как сделать экстенты чем-то отличным от 0.

Вот информация от коллайдеров и твердого тела, прикрепленного к изображению:

  • Box Collider 2D:
    • Используется Composite: true
    • Автоматическое разбиение: false
    • Смещение: (0,0)
    • Размер: (1,1)
  • Твердое тело 2D:
    • Тип кузова: кинематический
    • Материал: Нет (Физический материал 2D)
    • Имитация: true
    • Использовать полный кинематический контакт: false
    • Обнаружение столкновений: дискретно
    • Спящий режим: запуск при пробуждении
    • Интерполировать:Нет
    • Ограничения: Нет
  • Композитный коллайдер 2D:
    • Материал: Нет (физический материал 2D)
    • is Триггер: false
    • Используется эффектором: false
    • Смещение: (0,0)
    • Тип геометрии: полигоны
    • Тип генерации: Синхронный
    • Vertex Distance: 0,0005

Есть кнопка, которая включает и выключает транспортир с помощью следующего кода:

public void toggle() {
    this.enabled = !this.enabled;
    this.gameObject.SetActive(this.enabled);
}

Транспортир начинает жизнь видимымно Start() сразу звонит toggle(), поэтому пользователь видит, что он только начинается.

Это код, который выполняет тест, чтобы определить, нужно ли реагировать на прикосновения:

void checkTouches() {
    if (Input.touchCount <= 0) {
        return;
    }
    bool oneTouchIn = false;
    Collider2D collider = GetComponent<Collider2D>();
    Debug.Log("? The bounds of the collider are: " + collider.bounds); 
    // The above always logs the extents as (0,0,0).
    foreach (Touch touch in Input.touches) {
        Vector2 touchPos = Camera.main.ScreenToWorldPoint(touch.position);
        if(collider.OverlapPoint(touchPos)) {
            // Since the extents are all 0 we never find any overlaps
            oneTouchIn = true;
            break;
        }
    }
    if (!oneTouchIn) {
        return; // Always ends up here
    }
    // We must have at least one touch that is in our bounds.
    // Do stuff with the touch(es) here…
}

Я занимаюсь разработкой iOS для Objective-C с момента выпуска SDK и с Swift с момента его выхода, но я очень новичок в Unity.Я уверен, что проблема в том, что мне не хватает чего-то глупого, но я не могу его найти.

Кто-нибудь знает, что мне не хватает, чтобы заставить работать текущую версию, или альтернативный способ реагировать только на прикосновения, которыев границах?

1 Ответ

0 голосов
/ 01 марта 2019

У изображения, похоже, нет такого свойства

Нет, у самого Image componemt этого нет ...

Но rect свойство компонента RectTransform каждого пользовательского интерфейса GameObject.

Называется Содержит .Таким образом, вы можете сделать, например,

RectTransform imgRectTransform = imageObject.GetComponent<RectTransform>();
Vector2 localTouchPosition = imgRectTransform.InverseTransformPoint(Touch.position);
if (imgRectTransform.rect.Contains(localToichPosition)) { ... }

В качестве альтернативы вы можете использовать IPointerEnterHandler и IPointerExitHandler Интерфейсы в компоненте на целевом изображении, например,

public class DragableHandler : MonkBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    public bool IsHover {get; private set; }

    //Detect if the Cursor starts to pass over the GameObject
    public void OnPointerEnter(PointerEventData pointerEventData)
    {
        //Output to console the GameObject's name and the following message
        Debug.Log("Cursor Entering " + name + " GameObject");
        IsHover = true;
    }

    //Detect when Cursor leaves the GameObject
    public void OnPointerExit(PointerEventData pointerEventData)
    {
        //Output the following message with the GameObject's name
        Debug.Log("Cursor Exiting " + name + " GameObject");
        IsHover = false;
    }
}

, а затем в своем скрипте проверьте его, используя

if(imageObject.GetComponent<DragableHandler>().IsHover) { ... }

, просто убедитесь, что мы EventSystem добавляем Touch Input Module и отметим флаг Force Module Active.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...