Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Auto scroll panel

Discussion in 'UGUI & TextMesh Pro' started by WILEz1975, Dec 31, 2021.

  1. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    368
    Hi boys.
    I need a solution for a script that automatically scrolls the UI panel when a selected child element that appears outsideof the mask.
    I can select the UI childrens, scrolling with keys,up and down, both on the keyboard and on the joypad.

    In practice, in the image, if the last item is selected (Gold Coins of 27), on press "down" the content UI should scroll by a bit to display the next item.

    Screenshot_49.png


    I wrote this code but it still doesn't work as it should. I only care about the Y.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UIElements;
    6.  
    7. public class AutoScrollWinElement : MonoBehaviour
    8. {
    9.     public ElementsGroupNavigation elementsGroupNavigation;
    10.     public float minAutoScrollAt = -20;
    11.     public float maxAutoScrollAt = -285;
    12.     float autoScrollValue = 50;
    13.     public float defaultScrollValue = 50;
    14.  
    15.  
    16.     //ViewPort (not the scrollable content but the UI that remains stationary)
    17.     public RectTransform viewPort;
    18.     public float selectedPosition;
    19.  
    20.     //Update on selection changing
    21.     public void UpdateSelection()
    22.     {
    23.         if (!elementsGroupNavigation.CheckkSelected()) return;
    24.  
    25.         //Y position of selected element related to the viewPort position
    26.         selectedPosition = viewPort.transform.position.y- elementsGroupNavigation.CheckkSelected().transform.position.y;
    27.  
    28.  
    29.         if (selectedPosition < minAutoScrollAt){
    30.             autoScrollValue =  minAutoScrollAt - selectedPosition - defaultScrollValue;
    31.           transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y + autoScrollValue, transform.localPosition.z);
    32.         }
    33.         else
    34.             if (selectedPosition > maxAutoScrollAt)
    35.         {
    36.             autoScrollValue = maxAutoScrollAt - selectedPosition+ defaultScrollValue;
    37.             transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y - autoScrollValue, transform.localPosition.z);
    38.         }
    39.  
    40.  
    41.  
    42. }
    43.  
    44. }
    45.  
    46.  
     
    Last edited: Dec 31, 2021
  2. Fatcat-Games

    Fatcat-Games

    Joined:
    Nov 9, 2016
    Posts:
    34
    I won't answer this question for you directly, but I can set you in the right direction. Your going to want to use the normalizedPosition of the ScrollRect.

    Start by getting the scroll step ie. the amount the ScrollRect should scroll per item.
    Code (CSharp):
    1. if(childItems.Count > 1) scrollStep = 1f / (childItems.Count - 1);
    Then use the index of the childItem to scroll the ScrollRect to that position.
    Code (CSharp):
    1. normalizedPosition = new Vector2(normalizedPosition.x, 1f - childIndex * scrollStep);
    Hope this helps, good luck!
     
  3. WILEz1975

    WILEz1975

    Joined:
    Mar 23, 2013
    Posts:
    368


    Thanks for the reply.
    I used this script, it works, not great but it works.


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3. using UnityEngine.UI;
    4.  
    5.     public class vAutoScrollVertical : MonoBehaviour
    6.     {
    7.         private ScrollRect sr;
    8.         RectTransform contentRect;
    9.         public float adj =0;
    10.         public ElementsGroupNavigation elementsGroupNavigation;
    11.         public void Awake()
    12.         {
    13.             sr = this.gameObject.GetComponent<ScrollRect>();
    14.             if (sr)
    15.             {
    16.                 contentRect = sr.content;
    17.             }
    18.         }
    19.  
    20.         void Update()
    21.         {
    22.           //  OnUpdateSelected();
    23.         }
    24.      //   public float selectedPosition;
    25.         public void OnUpdateSelected()
    26.         {
    27.             if (!elementsGroupNavigation.CheckkSelected()) return;
    28.             GameObject selected = elementsGroupNavigation.CheckkSelected().gameObject;
    29.             if (selected == null || selected.transform.parent != contentRect.transform) return;
    30.  
    31.             //Y position of selected element
    32.           //  selectedPosition = sr.transform.position.y - elementsGroupNavigation.CheckkSelected().transform.position.y;
    33.  
    34.             // helper vars
    35.             float contentHeight = sr.content.rect.height;
    36.             float viewportHeight = sr.viewport.rect.height;
    37.  
    38.             // what bounds must be visible?
    39.             float centerLine = selected.transform.localPosition.y; // selected item's center
    40.             float upperBound = centerLine + (selected.GetComponent<RectTransform>().rect.height / 2f); // selected item's upper bound
    41.             float lowerBound = centerLine - (selected.GetComponent<RectTransform>().rect.height / 2f); // selected item's lower bound
    42.  
    43.             // what are the bounds of the currently visible area?
    44.             float lowerVisible = (contentHeight - viewportHeight) * sr.normalizedPosition.y - (contentHeight * 0.5f);
    45.             float upperVisible = lowerVisible + viewportHeight;
    46.  
    47.             // is our item visible right now?
    48.             float desiredLowerBound;
    49.             if (upperBound > upperVisible || elementsGroupNavigation.CheckkSelected().elementID.Equals(0))
    50.             {
    51.                 // need to scroll up to upperBound
    52.                 desiredLowerBound = upperBound - viewportHeight + selected.GetComponent<RectTransform>().rect.height+ adj;
    53.               //  print(upperBound+" UP "+ upperVisible);
    54.             }
    55.             else if (lowerBound < lowerVisible)
    56.             {
    57.              //   print(lowerBound + " DN " + lowerVisible);
    58.                 // need to scroll down to lowerBound
    59.                 desiredLowerBound = lowerBound - selected.GetComponent<RectTransform>().rect.height+ adj;
    60.             }
    61.  
    62.             else
    63.             {
    64.                 // item already visible - all good
    65.                 return;
    66.             }
    67.  
    68.             // normalize and set the desired viewport
    69.             float normalizedDesired = (desiredLowerBound + contentHeight) / (contentHeight - viewportHeight);
    70.             var normalizedPosition = new Vector2(0f, Mathf.Clamp01(normalizedDesired));
    71.             sr.normalizedPosition = normalizedPosition;// Vector2.Lerp(sr.normalizedPosition, normalizedPosition, 10 * Time.fixedDeltaTime);
    72.         }
    73.  
    74.     }
    75.  
    76.