Unity

ScrollViewのデフォルト位置を常時1番下にする

やりたいこと

  • ScrollView内のコンテンツの一番下にアイテムが追加された時、一番下にスクロールバーを下げたい。

  • コマンドライン風UI作ってる時にコマンドラインって画面が常時一番下にスクロールした状態になるのでこれがやりたかった。

こんな感じ

ConsoleTest.gif

やりかた

ScrollRect.verticalNormalizedPositionってパラメータをいじる

  • 0だと一番下
  • 1だと一番上

こんな感じの構成で
screenshot.png

ScrollView/ViewPort/Textを今回ScrollRectのContentに設定してる。screenshot.png

テキストにはContentSizeFilterをaddして
vertical FitをPrefferred Sizeにすることで自動で高さ調整
screenshot.png

InputFieldにConsoleTextCoreをaddしてOnEndEditでConsoleTextCore.OnInputを呼ぶようにする。
screenshot.png

ConsoleTextCore
public class ConsoleTextCore : MonoBehaviour
{
    private InputField _inputField;
    public Text ConsoleText;
    public ScrollRect ScrollRect;

    // Use this for initialization
    void Start ()
    {
        _inputField = GetComponent<InputField>();
        InitInputField();
    }

    // Update is called once per frame
    void Update () {

    }

    public void OnInput()
    {
        string inputValue = _inputField.text;
        WriteConsole(inputValue);
        InitInputField();
    }

    void WriteConsole(string text)
    {
        ConsoleText.text += "\n" + text;
    }



    void InitInputField() {

        // 値をリセット
        _inputField.text = "";


        // フォーカス
        _inputField.ActivateInputField();

        ScrollRect.verticalNormalizedPosition = 0; //ここでスクロールを一番下にする
    }
}

inputfieldが入力されたらOnInput()が呼ばれ、上のコンソール風にしたテキストに表示され、一番下にスクロールするようにした。

問題点

この方がおっしゃられているのですがこれをやってもなぜか一番下にならず微妙に余った状態になってしまう。

こんな感じでスクロールバーが下に行かない

ConsoleTest2.gif

よく見てみると更新された高さ分余ってる。
これscrollviewがコンテンツの高さ更新を認識してないのかなと思ったが、そもそも高さが更新されるのがポジションをいじるのより遅いんじゃねって考えた。
要はConsoleText.textにstring足すだけだとContentSizeFilterがその変更を反映してないときにポジション変更呼んじゃってるんじゃないかと。
なのでなんか高さ更新的なメソッド無いかなぁって探したら
ContentSizeFilter.SetLayoutVertical()ってのがあった。
めっちゃそれっぽい。
とりあえず呼んでみた。

public void WriteConsole(string text)
    {
        ConsoleText.text += "\n" + text;
        ConsoleText.GetComponent<ContentSizeFitter>().SetLayoutVertical();//<-これ追加
    }

動いた!!(再掲)
ConsoleTest.gif
この方法があってるかわからんけど明示的に高さ更新されたよって教えてあげるとなんかうまくいった。
間違ってたらすいません。今回の場合はうまくいきました。

まとめ

  1. コンテントにアイテムとか追加して高さを変える
  2. ContentSizeFitter.SetLayoutVertical()を呼んで明示的に高さを更新してあげる
  3. ScrollRect.verticalNormalizedPosition = 0(一番下にスクロール位置をもってく場合)と変更する。

以上!