- Home /
Can I use EventSystem + InputModule to implement scroll via button?
I can easily write a custom component whose sole purpose is to change the position of a scroll rect or the normalized position of a scroll bar. But this seems clumsy and inelegant.
I am trying to understand the EventSystem and InputModule architecture. The documentation is lacking. I've seen some derisive comments about how bad it is. But I still want to see if I can use it, and this seems like a good, focussed problem to practise on.
My high level idea is to transform a mouse click event into a scroll event.
What I would have liked would be a simple way to configure OnClick() in the editor to send a message that is interpreted as a scroll up or down, or something. Or perhaps one more level of complexity, to have a single intermediate, generic component that can send any input even to any object, and use that as the target of OnClick(). Maybe that would work with EventSystem.Execute()? The docs for Execute are very confusing, but I think I will try to experiment with it.
My second idea would be to write a simple input module that generated fake scroll deltas or something, and activate that from OnClick(). But I'm not clear at all on how the default input module and the override interact. Nor is it clear whether the scroll delta change will be picked up immediately by the event system, or if I have to simulate it for a duration, like 1/10th second or something.
Any experiences or suggestions appreciated.
Update: for those interested, this is my working fallback solution:
using UnityEngine;
using UnityEngine.UI;
using System;
[Serializable]
[RequireComponent(typeof(Scrollbar))]
public class StepScrollbar : MonoBehaviour {
[SerializeField]
Button upButton;
[SerializeField]
Button downButton;
[SerializeField, HideInInspector]
Scrollbar scrollbar;
float interval;
float value {
get => scrollbar.value;
set => scrollbar.value = value;
}
bool Max => Mathf.Abs(value - 1.0f) < Mathf.Epsilon;
bool Min => Mathf.Abs(value) < Mathf.Epsilon;
void Start() {
scrollbar = GetComponent<Scrollbar>();
interval = 1.0f / scrollbar.numberOfSteps;
UpdateButtons();
}
public void StepUp() {
if (!Max) {
value += interval;
if (Max) {
value = 1.0f;
}
}
UpdateButtons();
}
public void StepDown() {
if (!Min) {
value -= interval;
if (Min) {
value = 0;
}
}
UpdateButtons();
}
public void UpdateButtons() {
upButton.interactable = !Max;
downButton.interactable = !Min;
}
}