Как двигать слайдер при наведении курсора на ручку в Unity - PullRequest
0 голосов
/ 15 мая 2019

Я хочу, чтобы мой ползунок двигался, когда я наводил курсор на ручку и перемещал мышь. Я не хочу нажимать и перетаскивать ручку. Есть ли способ сделать это?

Я попытался с помощью onenter на своей ручке вызвать setselectedgameobject, чтобы установить выбранное для моего слайдера, а затем при выходе установить пустой игровой объект, но тогда мой слайдер не работает вообще. Я также попытался воссоздать код, названный в OnPointerDown слайдера, используя отражения и модифицирующие биты, чтобы он работал, пока моя мышь находится внутри RectTransform дескриптора. Это тоже не работает и заставляет мой слайдер вести себя странно. Он прыгает, сидя некоторое время на одном месте, вместо того, чтобы двигаться с моей мышью. Вполне возможно, что я могу просто неправильно скопировать и изменить код OnPointerDown или иным образом пропустить что-то, что делается в коде скрипта слайдера.

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

public class ScrubberSlider : Slider
{

    private void Update()
    {
        base.Update();
        if(InputTouchManager.isCurrentTS)
        {
            TSUpdateSliderPos();
        }
    }

    private void TSUpdateSliderPos()
    {

         StandaloneInputModule InputModule = GameObject.Find("EventSystem").GetComponent<StandaloneInputModule>();
         System.Type StandaloneInputModuleType = typeof(StandaloneInputModule).Assembly.GetType("UnityEngine.EventSystems.StandaloneInputModule");
         MethodInfo GetLastPointerEventData = StandaloneInputModuleType.GetMethod("GetLastPointerEventData", BindingFlags.Instance | BindingFlags.NonPublic);
         PointerEventData eventData = new PointerEventData(EventSystem.current);
         eventData.position = Application.platform == RuntimePlatform.Android ? (Vector3)Input.touches[0].position : Input.mousePosition;
         if (!IsActive() || !IsInteractable())
         {
             return;
         }

         if(IsInteractable() && navigation.mode != Navigation.Mode.None && EventSystem.current != null)
         {
             EventSystem.current.SetSelectedGameObject(gameObject, eventData);
         }

         System.Type SelectableType = typeof(Selectable).Assembly.GetType("UnityEngine.UI.Selectable");
         PropertyInfo isPointerDown = SelectableType.GetProperty("isPointerDown", BindingFlags.Instance | BindingFlags.NonPublic);
         isPointerDown.SetValue(this, true);

         DoStateTransition(SelectionState.Pressed, false);

         System.Type SliderType = typeof(Slider).Assembly.GetType("UnityEngine.UI.Slider");
         FieldInfo offset = SliderType.GetField("m_Offset", BindingFlags.Instance | BindingFlags.NonPublic);
         offset.SetValue(this, Vector2.zero);



         FieldInfo HandleContainerRect = SliderType.GetField("m_HandleContainerRect", BindingFlags.Instance | BindingFlags.NonPublic);
         FieldInfo HandleRect = SliderType.GetField("m_HandleRect", BindingFlags.Instance | BindingFlags.NonPublic);

         if (HandleContainerRect.GetValue(this)!=null && RectTransformUtility.RectangleContainsScreenPoint((RectTransform)HandleRect.GetValue(this), eventData.position, eventData.pressEventCamera) ){
             Vector2 localMousePos = Vector2.zero;
             if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)HandleRect.GetValue(this), eventData.position, Camera.main, out localMousePos))
             {
                 offset.SetValue(this, localMousePos);
             }
             MethodInfo UpdateDrag = SliderType.GetMethod("UpdateDrag", BindingFlags.Instance | BindingFlags.NonPublic);
             object[] UpdateDragParams = { eventData, Camera.main };
             UpdateDrag.Invoke(this, UpdateDragParams);
         }
         else
         {
             MethodInfo UpdateDrag = SliderType.GetMethod("UpdateDrag", BindingFlags.Instance | BindingFlags.NonPublic);
             object[] UpdateDragParams = { eventData, Camera.main };
             UpdateDrag.Invoke(this, UpdateDragParams);
         }

         MethodInfo UpdateVisuals = SliderType.GetMethod("UpdateVisuals", BindingFlags.Instance | BindingFlags.NonPublic);
         UpdateVisuals.Invoke(this,null);
    }

}

Выше приведен мой код, из которого я пытаюсь воссоздать OnPointerDown и заставить его работать, находясь просто внутри дескриптора. Любая и помощь приветствуется.

1 Ответ

0 голосов
/ 15 мая 2019

Что вы можете сделать:

1) захватить ползунок GetWorldCorners (), сохранить их.

2) занять позицию мыши, вычислить ее локальное положение в RectTransform слайдера (взять слайдер.direction)во внимание), нормализуйте, чтобы задать ширину / высоту

3) установить .normalizedValue ползунка на то, что выходит. Вы можете сделать это в сопрограмме, которая запускает OnPointerEnter и выходит из OnPointerExit.

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