「Unity/TMPro/Dropdown」の版間の差分

提供: 初心者エンジニアの簡易メモ
ナビゲーションに移動 検索に移動
62行目: 62行目:
public class TMPDropdownScrollFix : MonoBehaviour
public class TMPDropdownScrollFix : MonoBehaviour
{
{
    [SerializeField]
     public TMP_Dropdown dropdown;
     public TMP_Dropdown dropdown;
 
    [SerializeField]
    private Button button;
    void Start()
    {
        button.onClick.AddListener(() => OpenDropdownAsync().Forget());
    }
     public async UniTaskVoid OpenDropdownAsync()
     public async UniTaskVoid OpenDropdownAsync()
     {
     {

2026年2月10日 (火) 14:20時点における版

TMP_Dropdownのスクリプトで制御

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class SettingScene : MonoBehaviour
{
    TMP_Dropdown areaDropdown;
    List<string> areas;
    string area;
    void Start()
    {
        AreaDropdownInit();
        areaDropdown = this.transform.Find("AreaDropdown").GetComponent<TMP_Dropdown>();
        areaDropdown.onValueChanged.AddListener(delegate {
            AreaDropdownValueChanged(areaDropdown);
        });
    }
    void AreaDropdownInit()
    {
        areas = new List<string>();
        areas.Add("simple");
        areas.Add("sabaku");
        areas.Add("sushi");
        List<TMP_Dropdown.OptionData> optionMessages = new List<TMP_Dropdown.OptionData>();
        TMP_Dropdown areaDropdown = this.transform.Find("AreaDropdown").GetComponent<TMP_Dropdown>();
        areaDropdown.ClearOptions();
        foreach (string area in areas)
        {
            TMP_Dropdown.OptionData optionData;
            optionData = new TMP_Dropdown.OptionData();
            optionData.text = area;
            optionMessages.Add(optionData);
        }
        foreach (TMP_Dropdown.OptionData message in optionMessages)
        {
            areaDropdown.options.Add(message);
        }
        areaDropdown.value = areas.IndexOf(area);
        this.transform.Find("AreaDropdown/Label").GetComponent<TextMeshProUGUI>().text = areas[areaDropdown.value].ToString();
    }
    void AreaDropdownValueChanged(TMP_Dropdown change)
    {
        area = areas[change.value];
        this.transform.Find("AreaDropdown/Label").GetComponent<TextMeshProUGUI>().text = areas[areaDropdown.value].ToString();
    }
}

UIのButtonをDropdownに被せて、ButtonをクリックしたときにDropdownを開く以下処理を走らせる。

UniTaskバージョン

using Cysharp.Threading.Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class TMPDropdownScrollFix : MonoBehaviour
{
    [SerializeField]
    public TMP_Dropdown dropdown;
    [SerializeField]
    private Button button;
    void Start()
    {
        button.onClick.AddListener(() => OpenDropdownAsync().Forget());
    }
    public async UniTaskVoid OpenDropdownAsync()
    {
        dropdown.Show();
        await ScrollToSelectedAsync();
    }

    async UniTask ScrollToSelectedAsync()
    {
        // UI生成待ち(超重要)
        await UniTask.NextFrame();
        await UniTask.NextFrame();

        var scrollRect = dropdown.GetComponentInChildren<ScrollRect>();
        if (scrollRect == null) return;

        int index = dropdown.value;
        int count = dropdown.options.Count;

        if (count <= 1) return;

        float normalizedPos = 1f - (float)index / (count - 1);
        scrollRect.verticalNormalizedPosition = normalizedPos;
    }
}

コルーチンパターン

using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class TMPDropdownScrollFix : MonoBehaviour
{
    [SerializeField]
    public TMP_Dropdown dropdown;
    [SerializeField]
    private Button button;
    void Start()
    {
        button.onClick.AddListener(() => OpenDropdown());
    }
    void OpenDropdown()
    {
        dropdown.Show();
        StartCoroutine(ScrollToSelected());
    }

    IEnumerator ScrollToSelected()
    {
        // UI生成待ち(超重要)
        yield return null;
        yield return null;

        var scrollRect = dropdown.GetComponentInChildren<ScrollRect>();
        if (scrollRect == null) yield break;

        int index = dropdown.value;
        int count = dropdown.options.Count;

        // 上=1、下=0
        float normalizedPos = 1f - (float)index / (count - 1);

        scrollRect.verticalNormalizedPosition = normalizedPos;
    }
}