uGUIのDropdownを使うとドロップダウンリストを簡単に作れます。
ツールやメニュー画面に便利なアイテムですが、とても使いにくい点が1つあります。
スクロールが選択位置に同期してくれない!
選択項目が少ないうちは良いですが、多くなると致命的に不便です。
選択位置に同期させる設定があっても良さそうだけど、どうやら無いので…作りました。
using UnityEngine;
using UnityEngine.UI;
public class DropdownScrollTemplate : MonoBehaviour
{
private ScrollRect sr;
public void Awake()
{
sr = this.gameObject.GetComponent<ScrollRect>();
}
public void Start()
{
var dropdown = GetComponentInParent<Dropdown>();
if (dropdown != null)
{
var viewport = this.transform.Find("Viewport").GetComponent<RectTransform>();
var contentArea = this.transform.Find("Viewport/Content").GetComponent<RectTransform>();
var contentItem = this.transform.Find("Viewport/Content/Item").GetComponent<RectTransform>();
// Viewportに対するContentのスクロール位置を求める
var areaHeight = contentArea.rect.height - viewport.rect.height;
var cellHeight = contentItem.rect.height;
var scrollRatio = (cellHeight * dropdown.value) / areaHeight;
sr.verticalNormalizedPosition = 1.0f - Mathf.Clamp(scrollRatio, 0.0f, 1.0f);
}
}
}
このスクリプトをDropdownの子供にある Template に付けるとこうなります。
スクロールが選択位置にあわせて同期する理想の挙動になりました。
スクリプトはViewportに対するContentエリアのスクロール位置を計算で求めています。
見ての通りDropdownコンポーネント限定対応ですが、スクロールエリアがあるものには応用できそうです。
ついでに Scroll Sensitivity の値を調整しておくと良いでしょう。
マウスホイールでのスクロール感度が上がるので、更に使いやすいメニューになります。
デフォルトは1で微量の反応しかしませんが、20くらいにしておくと良い感じに反応してくれます。
もっと良い方法もありそうですが、とりあえず動けばOK!なら試してみてください。