「Unity/TMPro/Dropdown」の版間の差分
ナビゲーションに移動
検索に移動
| (同じ利用者による、間の5版が非表示) | |||
| 51行目: | 51行目: | ||
==Dropdownを開いたときに選択した項目を表示する方法== | ==Dropdownを開いたときに選択した項目を表示する方法== | ||
UIのButtonをDropdownに被せて(Imageを透明に)、ButtonをクリックしたときにDropdownを開く以下処理を走らせる。 | |||
選択Indexが表示領域の中央より上なら、スクロールしないように。 | 選択Indexが表示領域の中央より上なら、スクロールしないように。 | ||
| 75行目: | 75行目: | ||
{ | { | ||
dropdown.Show(); | dropdown.Show(); | ||
await | await DropdownScrollUtil.AdjustScroll(dropdown.gameObject); | ||
} | } | ||
} | |||
</pre> | |||
DropdownScrollUtil.cs | |||
<pre> | |||
using UnityEngine; | |||
using UnityEngine.UI; | |||
using Cysharp.Threading.Tasks; | |||
using TMPro; | |||
async UniTask | // Dropdownのスクロール位置調整 | ||
// 選択Indexが表示領域の中央より上なら、スクロールしないように | |||
// 使い方:await DropdownScrollUtil.AdjustScroll(dropdown.gameObject); | |||
public static class DropdownScrollUtil | |||
{ | |||
public static async UniTask AdjustScroll(GameObject dropdownObj) | |||
{ | { | ||
// | var dropdown = dropdownObj.GetComponent<TMP_Dropdown>(); | ||
if (dropdown == null) return; | |||
// UI生成待ち(Dropdown開いた直後は要る) | |||
await UniTask.NextFrame(); | await UniTask.NextFrame(); | ||
await UniTask.NextFrame(); | await UniTask.NextFrame(); | ||
| 91行目: | 107行目: | ||
if (totalCount <= 1) return; | if (totalCount <= 1) return; | ||
var viewport = scrollRect.viewport.rect.height; | var viewport = scrollRect.viewport.rect.height; | ||
var content = scrollRect.content; | var content = scrollRect.content; | ||
| 102行目: | 117行目: | ||
int centerIndex = visibleCount / 2; | int centerIndex = visibleCount / 2; | ||
// | // 中央まではスクロールしない | ||
if (index <= centerIndex) | if (index <= centerIndex) | ||
{ | { | ||
| 109行目: | 124行目: | ||
} | } | ||
float scrollIndex = index - centerIndex; | float scrollIndex = index - centerIndex; | ||
float maxScrollIndex = totalCount - visibleCount; | float maxScrollIndex = totalCount - visibleCount; | ||
| 145行目: | 159行目: | ||
{ | { | ||
dropdown.Show(); | dropdown.Show(); | ||
StartCoroutine( | StartCoroutine(DropdownScrollUtil.AdjustScroll(dropdown.gameObject)); | ||
} | } | ||
} | |||
</pre> | |||
DropdownScrollUtil.cs | |||
<pre> | |||
using System.Collections; | |||
using UnityEngine; | |||
using UnityEngine.UI; | |||
using TMPro; | |||
IEnumerator | // 使い方:StartCoroutine(DropdownScrollUtil.AdjustScroll(dropdown.gameObject)); | ||
public static class DropdownScrollUtil | |||
{ | |||
public static IEnumerator AdjustScroll(GameObject dropdownObj) | |||
{ | { | ||
// | var dropdown = dropdownObj.GetComponent<TMP_Dropdown>(); | ||
if (dropdown == null) yield break; | |||
// UI生成待ち | |||
yield return null; | yield return null; | ||
yield return null; | yield return null; | ||
var scrollRect = dropdown.GetComponentInChildren<ScrollRect>(); | var scrollRect = dropdown.GetComponentInChildren<ScrollRect>(); | ||
if (scrollRect == null) yield break; | if (scrollRect == null) yield break; | ||
int index = dropdown.value; | int index = dropdown.value; | ||
| 164行目: | 190行目: | ||
if (totalCount <= 1) yield break; | if (totalCount <= 1) yield break; | ||
var viewport = scrollRect.viewport.rect.height; | |||
var content = scrollRect.content; | |||
float itemHeight = | |||
if (content.childCount == 0) yield break; | |||
float itemHeight = ((RectTransform)content.GetChild(0)).rect.height; | |||
int visibleCount = Mathf.FloorToInt(viewport / itemHeight); | |||
int centerIndex = visibleCount / 2; | int centerIndex = visibleCount / 2; | ||
// | // 中央まではスクロールしない | ||
if (index <= centerIndex) | if (index <= centerIndex) | ||
{ | { | ||
| 179行目: | 207行目: | ||
} | } | ||
float scrollIndex = index - centerIndex; | |||
float maxScrollIndex = totalCount - visibleCount; | float maxScrollIndex = totalCount - visibleCount; | ||
if (maxScrollIndex <= 0) | if (maxScrollIndex <= 0) | ||
{ | { | ||
| 187行目: | 216行目: | ||
} | } | ||
float normalizedPos = 1f - (scrollIndex / maxScrollIndex); | float normalizedPos = 1f - (scrollIndex / maxScrollIndex); | ||
scrollRect.verticalNormalizedPosition = Mathf.Clamp01(normalizedPos); | scrollRect.verticalNormalizedPosition = Mathf.Clamp01(normalizedPos); | ||
} | } | ||
} | } | ||
</pre> | </pre> | ||
2026年3月22日 (日) 16:54時点における最新版
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();
}
}
Dropdownを開いたときに選択した項目を表示する方法
UIのButtonをDropdownに被せて(Imageを透明に)、ButtonをクリックしたときにDropdownを開く以下処理を走らせる。
選択Indexが表示領域の中央より上なら、スクロールしないように。
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 DropdownScrollUtil.AdjustScroll(dropdown.gameObject);
}
}
DropdownScrollUtil.cs
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using TMPro;
// Dropdownのスクロール位置調整
// 選択Indexが表示領域の中央より上なら、スクロールしないように
// 使い方:await DropdownScrollUtil.AdjustScroll(dropdown.gameObject);
public static class DropdownScrollUtil
{
public static async UniTask AdjustScroll(GameObject dropdownObj)
{
var dropdown = dropdownObj.GetComponent<TMP_Dropdown>();
if (dropdown == null) return;
// UI生成待ち(Dropdown開いた直後は要る)
await UniTask.NextFrame();
await UniTask.NextFrame();
var scrollRect = dropdown.GetComponentInChildren<ScrollRect>();
if (scrollRect == null) return;
int index = dropdown.value;
int totalCount = dropdown.options.Count;
if (totalCount <= 1) return;
var viewport = scrollRect.viewport.rect.height;
var content = scrollRect.content;
if (content.childCount == 0) return;
float itemHeight = ((RectTransform)content.GetChild(0)).rect.height;
int visibleCount = Mathf.FloorToInt(viewport / itemHeight);
int centerIndex = visibleCount / 2;
// 中央まではスクロールしない
if (index <= centerIndex)
{
scrollRect.verticalNormalizedPosition = 1f;
return;
}
float scrollIndex = index - centerIndex;
float maxScrollIndex = totalCount - visibleCount;
if (maxScrollIndex <= 0)
{
scrollRect.verticalNormalizedPosition = 1f;
return;
}
float normalizedPos = 1f - (scrollIndex / maxScrollIndex);
scrollRect.verticalNormalizedPosition = Mathf.Clamp01(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(DropdownScrollUtil.AdjustScroll(dropdown.gameObject));
}
}
DropdownScrollUtil.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
// 使い方:StartCoroutine(DropdownScrollUtil.AdjustScroll(dropdown.gameObject));
public static class DropdownScrollUtil
{
public static IEnumerator AdjustScroll(GameObject dropdownObj)
{
var dropdown = dropdownObj.GetComponent<TMP_Dropdown>();
if (dropdown == null) yield break;
// UI生成待ち
yield return null;
yield return null;
var scrollRect = dropdown.GetComponentInChildren<ScrollRect>();
if (scrollRect == null) yield break;
int index = dropdown.value;
int totalCount = dropdown.options.Count;
if (totalCount <= 1) yield break;
var viewport = scrollRect.viewport.rect.height;
var content = scrollRect.content;
if (content.childCount == 0) yield break;
float itemHeight = ((RectTransform)content.GetChild(0)).rect.height;
int visibleCount = Mathf.FloorToInt(viewport / itemHeight);
int centerIndex = visibleCount / 2;
// 中央まではスクロールしない
if (index <= centerIndex)
{
scrollRect.verticalNormalizedPosition = 1f;
yield break;
}
float scrollIndex = index - centerIndex;
float maxScrollIndex = totalCount - visibleCount;
if (maxScrollIndex <= 0)
{
scrollRect.verticalNormalizedPosition = 1f;
yield break;
}
float normalizedPos = 1f - (scrollIndex / maxScrollIndex);
scrollRect.verticalNormalizedPosition = Mathf.Clamp01(normalizedPos);
}
}