Задать вопрос

EventSystem. Почему метод IPointerUpHandler не вызывается(Объект EventSystem на сцене есть)?

EventSystem-объект на сцене есть. Также есть чужой скрипт джойстика, в котором аналогичные методы-события работают (проверено через отладчик). Объекты, скрипты которых должны получить события (VariableJoystick получает, а Selector нет)
5e89fc48cc8b1812027524.png
Содержимое Selector:
5e89fcc9300df400035143.png
Содержимое Joystick:
5e89fd4a1b744482080937.png
Содержимое EventSystem:
5e89fd5e83e6d063987330.png
Я не думаю, что дело в самих скриптах. Ведь в VariableJoystick методы-события работают. Ну решил, что листинги лучше, чем скрины. Это либо что-то очевидное, либо что-то неочевидное и печальное.
Код скриптов:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

namespace Assets.Antony.Code.UI
{
    public class LineGenerator : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
    {
        public Image ImageLine, Handle;
        public float LineCount;
        //float _lineSize;
        RectTransform _selectorBackground, _handle;
        Vector3 _startPosition;
        static readonly float sqrt2 = Mathf.Sqrt(2);
        void Start()
        {
            _selectorBackground = GetComponent<RectTransform>();
            _handle = Instantiate(Handle, transform).rectTransform;
            var stepAngle = 360 / LineCount;
            float currentAngle = 0;
            for (int i = 0; i < LineCount; i++)
            {
                Instantiate(ImageLine, transform).rectTransform.rotation = Quaternion.Euler(0, 0, currentAngle);
                currentAngle += stepAngle;
            }
        }

        public void OnPointerDown(PointerEventData eventData)
        {

        }
        public void OnDrag(PointerEventData eventData)
        {
            var handleRect = _handle.rect;
            var pointerPosition = eventData.position;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(_selectorBackground, pointerPosition, Camera.current, out var rectPosition);
            handleRect.position = rectPosition;
        }
        public void OnPointerUp(PointerEventData eventData)
        {

        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    public float Horizontal { get { return (snapX) ? SnapFloat(input.x, AxisOptions.Horizontal) : input.x; } }
    public float Vertical { get { return (snapY) ? SnapFloat(input.y, AxisOptions.Vertical) : input.y; } }
    public Vector2 Direction { get { return new Vector2(Horizontal, Vertical); } }

    public float HandleRange
    {
        get { return handleRange; }
        set { handleRange = Mathf.Abs(value); }
    }

    public float DeadZone
    {
        get { return deadZone; }
        set { deadZone = Mathf.Abs(value); }
    }

    public AxisOptions AxisOptions { get { return AxisOptions; } set { axisOptions = value; } }
    public bool SnapX { get { return snapX; } set { snapX = value; } }
    public bool SnapY { get { return snapY; } set { snapY = value; } }

    [SerializeField] private float handleRange = 1;
    [SerializeField] private float deadZone = 0;
    [SerializeField] private AxisOptions axisOptions = AxisOptions.Both;
    [SerializeField] private bool snapX = false;
    [SerializeField] private bool snapY = false;

    [SerializeField] protected RectTransform background = null;
    [SerializeField] private RectTransform handle = null;
    private RectTransform baseRect = null;

    private Canvas canvas;
    private Camera cam;

    private Vector2 input = Vector2.zero;

    protected virtual void Start()
    {
        HandleRange = handleRange;
        DeadZone = deadZone;
        baseRect = GetComponent<RectTransform>();
        canvas = GetComponentInParent<Canvas>();
        if (canvas == null)
            Debug.LogError("The Joystick is not placed inside a canvas");

        Vector2 center = new Vector2(0.5f, 0.5f);
        background.pivot = center;
        handle.anchorMin = center;
        handle.anchorMax = center;
        handle.pivot = center;
        handle.anchoredPosition = Vector2.zero;
    }

    public virtual void OnPointerDown(PointerEventData eventData)
    {
        OnDrag(eventData);
    }

    public void OnDrag(PointerEventData eventData)
    {
        cam = null;
        if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
            cam = canvas.worldCamera;

        Vector2 position = RectTransformUtility.WorldToScreenPoint(cam, background.position);
        Vector2 radius = background.sizeDelta / 2;
        input = (eventData.position - position) / (radius * canvas.scaleFactor);
        FormatInput();
        HandleInput(input.magnitude, input.normalized, radius, cam);
        handle.anchoredPosition = input * radius * handleRange;
    }

    protected virtual void HandleInput(float magnitude, Vector2 normalised, Vector2 radius, Camera cam)
    {
        if (magnitude > deadZone)
        {
            if (magnitude > 1)
                input = normalised;
        }
        else
            input = Vector2.zero;
    }

    private void FormatInput()
    {
        if (axisOptions == AxisOptions.Horizontal)
            input = new Vector2(input.x, 0f);
        else if (axisOptions == AxisOptions.Vertical)
            input = new Vector2(0f, input.y);
    }

    private float SnapFloat(float value, AxisOptions snapAxis)
    {
        if (value == 0)
            return value;

        if (axisOptions == AxisOptions.Both)
        {
            float angle = Vector2.Angle(input, Vector2.up);
            if (snapAxis == AxisOptions.Horizontal)
            {
                if (angle < 22.5f || angle > 157.5f)
                    return 0;
                else
                    return (value > 0) ? 1 : -1;
            }
            else if (snapAxis == AxisOptions.Vertical)
            {
                if (angle > 67.5f && angle < 112.5f)
                    return 0;
                else
                    return (value > 0) ? 1 : -1;
            }
            return value;
        }
        else
        {
            if (value > 0)
                return 1;
            if (value < 0)
                return -1;
        }
        return 0;
    }

    public virtual void OnPointerUp(PointerEventData eventData)
    {
        input = Vector2.zero;
        handle.anchoredPosition = Vector2.zero;
    }

    protected Vector2 ScreenPointToAnchoredPosition(Vector2 screenPosition)
    {
        Vector2 localPoint = Vector2.zero;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(baseRect, screenPosition, cam, out localPoint))
        {
            Vector2 pivotOffset = baseRect.pivot * baseRect.sizeDelta;
            return localPoint - (background.anchorMax * baseRect.sizeDelta) + pivotOffset;
        }
        return Vector2.zero;
    }
}

public enum AxisOptions { Both, Horizontal, Vertical }
  • Вопрос задан
  • 285 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
RAEvski
@RAEvski Автор вопроса
Кодер
Как выяснилось rect объекта Joystick перекрывает мой селектор, из-за чего он не реагирует на нажатия. Причем это предполагала логика работы Variable Joystick: он должен был реагировать на нажатия в любой области экрана из-за чего его rect-область сделали на всю сцену.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы