Search Unity

Scrollview scroll position

Discussion in 'UGUI & TextMesh Pro' started by akpriest, Mar 27, 2017.

  1. akpriest

    akpriest

    Joined:
    Jul 20, 2016
    Posts:
    5
    I have a scrollview set up inside my canvas. I would like to set the position of that scroll view to a specific gameobject in the content section of the scroll view. How would I do this?

    Or even just programmatically change the position of the scroll position inside of the scroll view. Thanks
     
  2. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    You calculate the scroll value based on the ratio between element position and content height
    Code (CSharp):
    1.             public RectTransform _element;
    2.  
    3.             ScrollRect scrollRect = GetComponent<ScrollRect>();
    4.             float scrollValue = 1 + _element.anchoredPosition.y/scrollRect.content.GetHeight();
    5.             scrollRect.verticalScrollbar.value = _scrollValue;
     
  3. Nukode

    Nukode

    Joined:
    May 24, 2016
    Posts:
    9
    Works super fine, it's slightly inaccurate with objects at the edges but that's fine, thanks :)
     
  4. Koyemsi

    Koyemsi

    Joined:
    Sep 25, 2017
    Posts:
    29
    Unfortunately, it doesn't work for me.
    First thing, scrollRect.content.GetHeight() throws an error, so I modified line 4 :

       float scrollValue = 1 + _element.anchoredPosition.y/scrollRect.content.rect.height;


    Now the script is ok, but the content behaves oddly. Sometimes it works, as the desired element is visible (but the content seems "randomly" positioned vertically) ; and sometimes not, as the element remains off screen.

    I must specify that my UI content is a complex spreadsheet with lines and columns, so it uses a lot of Layout components (Groups, Elements) and moreover a Content Size Fitter on the Content game object. I suspect this to be the problem, as the size of the Content may be recalculated with some delay.
    Also my Canvas has a Canvas Scaler which may cause additional mess.

    I will try your script with a more simple content... but I still need a solution to my own problem.
     
    Last edited: Jun 5, 2022
  5. Koyemsi

    Koyemsi

    Joined:
    Sep 25, 2017
    Posts:
    29
    I found another solution on Stack Overflow which works well for me :
    https://stackoverflow.com/a/30769550

    Here's my own code, slightly modified :
    Code (CSharp):
    1. RectTransform contentRt = content.GetComponent<RectTransform>();
    2.  
    3. void ScrollTo(Transform target) {
    4.     Canvas.ForceUpdateCanvases();
    5.     contentRt.anchoredPosition = (Vector2)scrollRect.transform.InverseTransformPoint(contentRt.position) - (Vector2)scrollRect.transform.InverseTransformPoint(target.position);
    6. }
    Be aware that this will act on both content's x and y position.
    If you want to modify only one coordinate, let's say the vertical one, use this code instead :
    Code (CSharp):
    1. RectTransform contentRt = content.GetComponent<RectTransform>();
    2.  
    3. void ScrollTo(Transform target) {
    4.     Canvas.ForceUpdateCanvases();
    5.     Vector2 offset = (Vector2)scrollRect.transform.InverseTransformPoint(contentRt.position) - (Vector2)scrollRect.transform.InverseTransformPoint(target.position);
    6.     Vector2 anchor = contentRt.anchoredPosition;
    7.     anchor.y = offset.y;
    8.     contentRt.anchoredPosition = anchor;
    9. }
    For the horizontal version, simply replace y by x on line 7.
     
    euivtui4h likes this.