This is the 30th day of my participation in the August Text Challenge.More challenges in August
An overview of the
When we use the untiy UGUI SCrollView, often have this problem, is when the SCrollView long, want to find one of these Item is very difficult, often need to find a long time, very trouble, today is mainly explain the SCrollView positioning function, According to the index of the Item, let the slider directly display the corresponding position of the Item.
Thought analysis
If you want to position the slider, the first thing you need to know is what parameter ScrollView is controlled by, and if you look at the API, you can see, He is controlled by VerticalNormalizedPosition and HorizontalNormalizedPosition its longitudinal and lateral sliding, so we and they range between 0 and 1, what we need through the location of the item, VerticalNormalizedPosition indirectly calculated and HorizontalNormalizedPosition value, thus to control the ScrollView positioning
Function implementation
Scenario building
1. Create a ScrollView and create multiple items within the Content. Then add groups VerticalLayoutGroup (auto-arrange components, added according to arrangement requirements) and ContentSizeFitter (auto-set width) to the Content. The final interface is as follows:
2. Add the button corresponding to the number of items, so that it can be clicked for positioning. Here we use GridLayoutGroup (also automatic patting column), faster automatic patting column, no need to place one by one
Code implementation
Let’s take a look at the code, first to rule out a few unlocatable cases, and then we’ll move on.
1, ScrollView has no Content or Viewport, which indicates that the ScrollView is empty. In this case, we can only exit the ScrollView
If (scrollRect. Viewport = = null | | scrollRect. The content = = null) {Debug. LogError (" ScrollView content or viewport is empty "); return inverse ? 1:0; }Copy the code
If there is no object under Content or if it is not a RectTransform, this will check if there is an object under ScrollView, and if the ScrollView is valid in canvas. If there is no object under Content, this will not work
var childTrans = scrollRect.content.GetChild(0) as RectTransform; If (childTrans == null) {debug. LogError(" No object under Content or not RectTransform"); return inverse ? 1:0; }Copy the code
3. Only one vertical and horizontal can be checked. There are some problems with the calculation of the two checked at the same time, which may be supplemented after modification
Horizontal && ScrollRect. horizontal) {debug. LogError(" Horizontal and vertical can only be checked "); return inverse ? 1:0; }Copy the code
4. Failed to obtain VerticalLayoutGroup or HorizontalLayoutGroup. This is mainly because I used the beat column combination
VerticalLayoutGroup group = scrollRect.content.GetComponent<VerticalLayoutGroup>(); If (group == null) {debug. LogError(" Failed to get VerticalLayoutGroup "); return inverse ? 1:0; }Copy the code
HorizontalLayoutGroup group = scrollRect.content.gameObject.GetComponent<HorizontalLayoutGroup>(); If (group == null) {debug. LogError(" Get HorizontalLayoutGroup failed "); return inverse ? 1:0; }Copy the code
5. The next step is to calculate the position and obtain the corresponding value. Horizontal or Vertical: Horizontal: rect.Width: Vertical: rect.Hight There is another distinguishing problem here, which is the inverse problem of the slider, that is, from top to bottom, from right to left to reverse, need to consider whether to use 1- to calculate the value. Second, get a couple of values the width or height of each item, plus the value is the interval set by the component, which is to be added
float elementLength = childrenRect.height + group.spacing;
Copy the code
The difference between Content. rect and viewPort. rect
var diff = contentRect.height - viewportRect.height;
Copy the code
After calculating all the values, we start to calculate the values, where pixelOffset is the pixelOffset, downward to the right is positive, optional, as required
if (inverse)
return Mathf.Clamp01(1 - (currentChildIndex * elementLength + pixelOffset) / diff);
else
return Mathf.Clamp01((currentChildIndex * elementLength - pixelOffset) / diff);
Copy the code
Results show
You can also imagine, for example, adding highlighting to the positioned Item, which may be supplemented later
Source code sharing
This is the project project file GitHub download address: click here to jump to download
Write in the last
All the shared content is the author used in the daily development process of a variety of small function points, sharing is also a way to review, if there is a bad place to write, please give more advice. Welcome to learn from each other and make progress. This piece article is written here first, hope to be able to help you