「Unity/UIScrollView」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→スクロールの中にtextを表示) |
(→選択Indexが表示領域の中央より上なら、スクロールしないように) |
||
| (同じ利用者による、間の44版が非表示) | |||
| 行1: | 行1: | ||
| − | == | + | ==縦スクロールの中にtextを表示== |
#HierarchyにUI/ScrollViewで作成 | #HierarchyにUI/ScrollViewで作成 | ||
| − | # | + | #ScrollViewのViewportのContentの下で、左クリックから、UI/Textを新規追加 |
| + | #ScrollViewのViewportのContentの下のTextを選択し、AddComponentでContentSizeFitterを追加 | ||
| + | #ContentSizeFitterのVerticalfitをUnconstrainedからPreferredSizeにする | ||
| + | #ScrollViewのViewportのContentを選択し、AddComponentでContentSizeFitterを追加 | ||
| + | #ContentSizeFitterのVerticalfitをUnconstrainedからPreferredSizeにする | ||
| + | #ScrollViewのViewportのContentの下のTextを選択し、LayoutElementを追加 | ||
| + | #ScrollViewのViewportのContentを選択し、VerticalLayoutGroupを追加 | ||
| + | #VerticalLayoutGroupのControlChildSizeのHeightとWidthにチェック。ChildForceExpandのHeightとWidthにチェック。 | ||
| + | #VerticalLayoutGroupののPaddingのLeft,Rightを10、Top,Bottomを5。 | ||
| + | #ScrollViewのViewportのContentの縦サイズは、コンテンツの縦サイズにフィットさせ、windowからは、はみ出る感じにする。 | ||
| + | |||
| + | c#から文字を追加する場合はこんな感じ | ||
| + | GameObject text = GameObject.Find("/Canvas/Scroll View/Viewport/Content/Text"); | ||
| + | text.GetComponent<Text>().text = @"利用規約 | ||
| + | この利用規約~"; | ||
| + | |||
| + | ==スクロールバーをスクロールの下に移動する== | ||
| + | scroll.verticalNormalizedPosition = 0;を追加すればよいが、 | ||
| + | スクロールが一番下の1つ上までしか、いかないので、 | ||
| + | 表示処理の0.1秒後ぐらいに、実行すると、一番下まで行く。 | ||
| + | (処理時は、UIにまで、テキストが適用されないので、一旦処理を抜けて、処理すると適用されるような感じ) | ||
| + | <pre> | ||
| + | void UpdateMessage() | ||
| + | { | ||
| + | // ここに更新処理を記述 | ||
| + | Invoke("ScrollDownGui", 0.1f); | ||
| + | } | ||
| + | void ScrollDownGui() | ||
| + | { | ||
| + | // スクロール下へ | ||
| + | GameObject content = GameObject.Find("/Canvas/Scroll View/Viewport/Content"); | ||
| + | GameObject scrollObj = GameObject.Find("/Canvas/Scroll View/"); | ||
| + | ScrollRect scroll = scrollObj.GetComponent<ScrollRect>(); | ||
| + | scroll.verticalNormalizedPosition = 0; | ||
| + | content.GetComponent<ContentSizeFitter>().SetLayoutVertical(); | ||
| + | } | ||
| + | </pre> | ||
| + | 参考:https://qiita.com/sonken625/items/adb6100f9f6d76dbdce4 | ||
| + | |||
| + | ===スクロール縦幅が変更されると常に一番下へ=== | ||
| + | <pre> | ||
| + | scrollRect.onValueChanged.AddListener((Vector2 value) => | ||
| + | { | ||
| + | scrollRect.verticalNormalizedPosition = 0f; | ||
| + | }); | ||
| + | </pre> | ||
| + | ===UniRxを使ってスクロール下へ移動する=== | ||
| + | Contentの縦幅変更を、検知するとスクロール下へ移動するように | ||
| + | <pre> | ||
| + | [SerializeField] RectTransform content; // ScrollView/Viewport/Content | ||
| + | [SeralizeField]] scrollRect; // ScrollView | ||
| + | content.ObserveEveryValueChanged(_ => _.sizeDelta.y) | ||
| + | .Subscribe(text => { | ||
| + | if (scrollRect != null) | ||
| + | { | ||
| + | scrollRect.verticalNormalizedPosition = 0; | ||
| + | } | ||
| + | }) | ||
| + | .AddTo(gameObject); | ||
| + | </pre> | ||
| + | |||
| + | ==一番下を基準にコンテンツを表示する== | ||
| + | ScrollView/Viewport/ContentのInspectorのPivotのyを1から0へ | ||
| + | |||
| + | ==スクロールView内にマテリアルを入れるとはみ出る== | ||
| + | 以下のような対応をすれば良いかも。 | ||
| + | *可能であれば、マテリアルを使わない。 | ||
| + | *ScrollViewにaddComponents/RectMask2Dを設定 | ||
| + | |||
| + | 参考:https://tech.pjin.jp/blog/2017/02/22/unity_ugui_scrollbar/ | ||
| + | |||
| + | 参考:https://teratail.com/questions/98004 | ||
| + | |||
| + | ==動的にリスト表示する時== | ||
| + | [[unity/リスト表示]] [ショートカット] | ||
| + | |||
| + | ==横スクロールバー削除== | ||
| + | #ScrollView内のScrollbarHorizontalを、削除 | ||
| + | #ScrollViewのInspectorのScrollRectのHorizontalScrollbarを、noneへ | ||
| + | |||
| + | 参考:https://www.chuken-engineer.com/entry/2019/11/12/160221#%E6%A8%AA%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%90%E3%83%BC%E3%82%92%E7%84%A1%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B | ||
| + | |||
| + | ==ドラッグ移動をなくす== | ||
| + | 縦の場合は、 | ||
| + | ScrollViewのInspectorのScrollRectからVerticalのチェックを外す。 | ||
| + | |||
| + | 横の場合は、 | ||
| + | ScrollViewのInspectorのScrollRectからHorizontalのチェックを外す。 | ||
| + | |||
| + | ==スクロールを指定のコンテンツに移動する== | ||
| + | 3番目のコンテンツに移動 | ||
| + | <pre> | ||
| + | int itemNum = 3; | ||
| + | GameObject content = GameObject.Find("Canvas/Panel/Scroll View/Viewport/Content"); | ||
| + | content.transform.localPosition = new Vector3(0, content.GetComponent<VerticalLayoutGroup>().spacing * (itemNum - 1), 0); | ||
| + | </pre> | ||
| + | |||
| + | コンテンツを中断に出す場合Scroll Viewの幅の半分を、コンテンツ座標のyから引く | ||
| + | <pre> | ||
| + | int itemNum = 3; | ||
| + | GameObject content = GameObject.Find("Canvas/Panel/Scroll View/Viewport/Content"); | ||
| + | content.transform.localPosition = new Vector3(0, content.GetComponent<VerticalLayoutGroup>().spacing * (itemNum - 1) - scroll.transform.parent.transform.parent.GetComponent<RectTransform>().sizeDelta.y / 2, 0); | ||
| + | </pre> | ||
| + | すぐ表示すると、何故かy軸が小さくなって表示されてしまう場合は、少し遅延させる | ||
| + | <pre> | ||
| + | int itemNum = 3; | ||
| + | Observable.Timer(System.TimeSpan.FromSeconds(0.01f)) | ||
| + | .Subscribe(_ => { | ||
| + | GameObject content = GameObject.Find("Canvas/Panel/Scroll View/Viewport/Content"); | ||
| + | content.transform.localPosition = new Vector3(0, | ||
| + | content.GetComponent<VerticalLayoutGroup>().spacing * (itemNum - 1) - scroll.transform.parent.transform.parent.GetComponent<RectTransform>().sizeDelta.y / 2, 0); | ||
| + | }) | ||
| + | .AddTo(gameObject); | ||
| + | </pre> | ||
| + | |||
| + | ==スクロールを2重化したとき、子供側のスクロールを無効にする方法== | ||
| + | #子供側のScrollViewのenableをオフにする | ||
| + | #ScrollView/Scrollbar HorizontalのActiveをオフに | ||
| + | #ScrollView/Scrollbar VerticalのActiveをオフに | ||
| + | |||
| + | ==選択Indexが表示領域の中央より上なら、スクロールしないように== | ||
| + | 呼び出し | ||
| + | GameObject scroll = GameObject.Find("Scroll View/Viewport/Content"); | ||
| + | int index = 1; | ||
| + | ScrollUtil.AdjustScroll(scroll, index); | ||
| + | |||
| + | ScrollUtil.cs | ||
| + | <pre> | ||
| + | using UnityEngine; | ||
| + | using UnityEngine.UI; | ||
| + | |||
| + | public static class ScrollUtil | ||
| + | { | ||
| + | // スクロール位置調整 | ||
| + | // 選択Indexが表示領域の中央より上なら、スクロールしないように | ||
| + | public static void AdjustScroll(GameObject scroll, int index) | ||
| + | { | ||
| + | var layout = scroll.GetComponent<VerticalLayoutGroup>(); | ||
| + | var content = scroll.GetComponent<RectTransform>(); | ||
| + | var scrollRect = scroll.GetComponentInParent<ScrollRect>(); | ||
| + | |||
| + | if (scrollRect == null) return; | ||
| + | |||
| + | if (content == null || layout == null) return; | ||
| + | if (content.childCount == 0) return; | ||
| + | |||
| + | Canvas.ForceUpdateCanvases(); | ||
| + | LayoutRebuilder.ForceRebuildLayoutImmediate(content); | ||
| + | |||
| + | float viewportHeight = scrollRect.viewport.rect.height; | ||
| + | |||
| + | float itemHeight = | ||
| + | ((RectTransform)content.GetChild(0)).rect.height + | ||
| + | layout.spacing; | ||
| + | |||
| + | int totalCount = content.childCount; | ||
| + | |||
| + | int visibleCount = Mathf.FloorToInt(viewportHeight / itemHeight); | ||
| + | int centerIndex = visibleCount / 2; | ||
| + | |||
| + | int scrollIndex = index - centerIndex; | ||
| + | |||
| + | int maxScrollIndex = totalCount - visibleCount; | ||
| + | |||
| + | if (maxScrollIndex <= 0) | ||
| + | { | ||
| + | scrollRect.verticalNormalizedPosition = 1f; | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | scrollIndex = Mathf.Clamp(scrollIndex, 0, maxScrollIndex); | ||
| + | |||
| + | float normalizedPos = 1f - ((float)scrollIndex / maxScrollIndex); | ||
| + | |||
| + | scrollRect.verticalNormalizedPosition = Mathf.Clamp01(normalizedPos); | ||
| + | } | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | ==ScrollBar== | ||
| + | https://futabazemi.net/unity/scroll_bar/ | ||
2026年3月14日 (土) 03:03時点における最新版
目次
縦スクロールの中にtextを表示
- HierarchyにUI/ScrollViewで作成
- ScrollViewのViewportのContentの下で、左クリックから、UI/Textを新規追加
- ScrollViewのViewportのContentの下のTextを選択し、AddComponentでContentSizeFitterを追加
- ContentSizeFitterのVerticalfitをUnconstrainedからPreferredSizeにする
- ScrollViewのViewportのContentを選択し、AddComponentでContentSizeFitterを追加
- ContentSizeFitterのVerticalfitをUnconstrainedからPreferredSizeにする
- ScrollViewのViewportのContentの下のTextを選択し、LayoutElementを追加
- ScrollViewのViewportのContentを選択し、VerticalLayoutGroupを追加
- VerticalLayoutGroupのControlChildSizeのHeightとWidthにチェック。ChildForceExpandのHeightとWidthにチェック。
- VerticalLayoutGroupののPaddingのLeft,Rightを10、Top,Bottomを5。
- ScrollViewのViewportのContentの縦サイズは、コンテンツの縦サイズにフィットさせ、windowからは、はみ出る感じにする。
c#から文字を追加する場合はこんな感じ
GameObject text = GameObject.Find("/Canvas/Scroll View/Viewport/Content/Text");
text.GetComponent<Text>().text = @"利用規約
この利用規約~";
スクロールバーをスクロールの下に移動する
scroll.verticalNormalizedPosition = 0;を追加すればよいが、 スクロールが一番下の1つ上までしか、いかないので、 表示処理の0.1秒後ぐらいに、実行すると、一番下まで行く。 (処理時は、UIにまで、テキストが適用されないので、一旦処理を抜けて、処理すると適用されるような感じ)
void UpdateMessage()
{
// ここに更新処理を記述
Invoke("ScrollDownGui", 0.1f);
}
void ScrollDownGui()
{
// スクロール下へ
GameObject content = GameObject.Find("/Canvas/Scroll View/Viewport/Content");
GameObject scrollObj = GameObject.Find("/Canvas/Scroll View/");
ScrollRect scroll = scrollObj.GetComponent<ScrollRect>();
scroll.verticalNormalizedPosition = 0;
content.GetComponent<ContentSizeFitter>().SetLayoutVertical();
}
参考:https://qiita.com/sonken625/items/adb6100f9f6d76dbdce4
スクロール縦幅が変更されると常に一番下へ
scrollRect.onValueChanged.AddListener((Vector2 value) =>
{
scrollRect.verticalNormalizedPosition = 0f;
});
UniRxを使ってスクロール下へ移動する
Contentの縦幅変更を、検知するとスクロール下へ移動するように
[SerializeField] RectTransform content; // ScrollView/Viewport/Content
[SeralizeField]] scrollRect; // ScrollView
content.ObserveEveryValueChanged(_ => _.sizeDelta.y)
.Subscribe(text => {
if (scrollRect != null)
{
scrollRect.verticalNormalizedPosition = 0;
}
})
.AddTo(gameObject);
一番下を基準にコンテンツを表示する
ScrollView/Viewport/ContentのInspectorのPivotのyを1から0へ
スクロールView内にマテリアルを入れるとはみ出る
以下のような対応をすれば良いかも。
- 可能であれば、マテリアルを使わない。
- ScrollViewにaddComponents/RectMask2Dを設定
参考:https://tech.pjin.jp/blog/2017/02/22/unity_ugui_scrollbar/
参考:https://teratail.com/questions/98004
動的にリスト表示する時
unity/リスト表示 [ショートカット]
横スクロールバー削除
- ScrollView内のScrollbarHorizontalを、削除
- ScrollViewのInspectorのScrollRectのHorizontalScrollbarを、noneへ
ドラッグ移動をなくす
縦の場合は、 ScrollViewのInspectorのScrollRectからVerticalのチェックを外す。
横の場合は、 ScrollViewのInspectorのScrollRectからHorizontalのチェックを外す。
スクロールを指定のコンテンツに移動する
3番目のコンテンツに移動
int itemNum = 3;
GameObject content = GameObject.Find("Canvas/Panel/Scroll View/Viewport/Content");
content.transform.localPosition = new Vector3(0, content.GetComponent<VerticalLayoutGroup>().spacing * (itemNum - 1), 0);
コンテンツを中断に出す場合Scroll Viewの幅の半分を、コンテンツ座標のyから引く
int itemNum = 3;
GameObject content = GameObject.Find("Canvas/Panel/Scroll View/Viewport/Content");
content.transform.localPosition = new Vector3(0, content.GetComponent<VerticalLayoutGroup>().spacing * (itemNum - 1) - scroll.transform.parent.transform.parent.GetComponent<RectTransform>().sizeDelta.y / 2, 0);
すぐ表示すると、何故かy軸が小さくなって表示されてしまう場合は、少し遅延させる
int itemNum = 3;
Observable.Timer(System.TimeSpan.FromSeconds(0.01f))
.Subscribe(_ => {
GameObject content = GameObject.Find("Canvas/Panel/Scroll View/Viewport/Content");
content.transform.localPosition = new Vector3(0,
content.GetComponent<VerticalLayoutGroup>().spacing * (itemNum - 1) - scroll.transform.parent.transform.parent.GetComponent<RectTransform>().sizeDelta.y / 2, 0);
})
.AddTo(gameObject);
スクロールを2重化したとき、子供側のスクロールを無効にする方法
- 子供側のScrollViewのenableをオフにする
- ScrollView/Scrollbar HorizontalのActiveをオフに
- ScrollView/Scrollbar VerticalのActiveをオフに
選択Indexが表示領域の中央より上なら、スクロールしないように
呼び出し
GameObject scroll = GameObject.Find("Scroll View/Viewport/Content");
int index = 1;
ScrollUtil.AdjustScroll(scroll, index);
ScrollUtil.cs
using UnityEngine;
using UnityEngine.UI;
public static class ScrollUtil
{
// スクロール位置調整
// 選択Indexが表示領域の中央より上なら、スクロールしないように
public static void AdjustScroll(GameObject scroll, int index)
{
var layout = scroll.GetComponent<VerticalLayoutGroup>();
var content = scroll.GetComponent<RectTransform>();
var scrollRect = scroll.GetComponentInParent<ScrollRect>();
if (scrollRect == null) return;
if (content == null || layout == null) return;
if (content.childCount == 0) return;
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
float viewportHeight = scrollRect.viewport.rect.height;
float itemHeight =
((RectTransform)content.GetChild(0)).rect.height +
layout.spacing;
int totalCount = content.childCount;
int visibleCount = Mathf.FloorToInt(viewportHeight / itemHeight);
int centerIndex = visibleCount / 2;
int scrollIndex = index - centerIndex;
int maxScrollIndex = totalCount - visibleCount;
if (maxScrollIndex <= 0)
{
scrollRect.verticalNormalizedPosition = 1f;
return;
}
scrollIndex = Mathf.Clamp(scrollIndex, 0, maxScrollIndex);
float normalizedPos = 1f - ((float)scrollIndex / maxScrollIndex);
scrollRect.verticalNormalizedPosition = Mathf.Clamp01(normalizedPos);
}
}
