将鼠标悬停在Unity中的旋钮上时如何移动滑块

时间:2019-05-14 21:41:08

标签: c# user-interface unity3d slider

当我将鼠标悬停在旋钮上并移动鼠标时,我想使滑块移动。我不需要单击并拖动旋钮。有办法吗?

我尝试在旋钮上使用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 :(得分:0)

您可以做的是:

1)抓住滑块的GetWorldCorners(),将其存储。

2)获取鼠标位置,计算其在滑块的RectTransform中的局部位置(将sliders.direction考虑在内),标准化为矩形的宽度/高度

3)将滑块的.normalizedValue设置为任何结果 您可以在启动OnPointerEnter并退出OnPointerExit的协同程序中完成此操作。