Hello. I’ve got a moveable scroll bar, and want to make a rotating wheel of icons that grow to 100% as they reach the centre of the screen - then shrink as they move away from it. Can anyone help me do this? I don’t really have much in the way of code as I’ve never tried this before and have no idea what I’m doing.
float distance = Vector3.Distance(d.transform.localPosition, Vector3.zero);
float f = Mathf.InverseLerp(d.transform.localPosition.y, Screen.height, distance);
d.transform.localScale = new Vector3(f, f, f);
How is the ‘rotating wheel of icons’ structured and what is it made of? Are these UI Images? Or are they sprites? 3D objects? If it’s all UI, then what mode is your Canvas in (overlay/camera/world)? We need more information.
Juat a scroll rect with content fitters and a layout group. Im using button images at the moment. 2D objects, in a line. Canvas is in the default 2D unity layout, but I can happily change it.
Not sure without seeing more, but is there a way to parent all the icons to an empty GO that’s in the center, then scale the parent? Similar to the radial array mentioned above, you can easily rotate and scale it. It would work with 3D objects, not sure about a UI case though. Interesting idea.
This is a mock-up of the effect I’m trying to get. Icons tapering off as they leave the main focus. Move the scroll, and they would get bigger towards the centre.

But if the scroll is at its extreme values (zero or one), then some of the extreme icons won’t “reach” the center and will remain at the top or bottom. Then you need to add padding top and bottom, and it will look something like this:

Without padding, the enlargement of the extreme icons occurs not in the center, but at the edges:

I took the standard Scroll View as a basis and left only vertical scroll for it. I added components to the Content object (which is inside) so that it would automatically arrange objects inside itself and adjust its size to its content:
-
VerticalLayout (adjusting the values in padding, if necessary). And left the flags only for Use Child Size for width and height (since we will control the size of these objects).
-
ContentSizeFitter with VerticalSize set to MinSize.
And I added this script directly to the main Scroll View object. Here you need to set the minimum and maximum size for the icons. As well as a curve to adjust the smoothness of this size change, my curve is quite sharp (so that the icons decrease fairly quickly):

But I’m not very happy with this implementation. Sometimes there are some jerks when scrolling. Obviously, this is related to some internal processes of the ScrollView itself, which constantly tries to update the scroll position when the content size changes, and the scroll, in turn, tries to “fit” the content into the correct position.
In general, the solution turned out to be clumsy, and it seems better to start from scratch. Either carefully study how this UI works and how to control it correctly. Alas, I never really made friends with UI.
using System;
using UnityEngine;
using UnityEngine.UI;
public class ScrollScaleExample : MonoBehaviour
{
public float MinScale = 1f;
public float MaxScale = 3f;
public AnimationCurve ScaleCurve;
private ScrollRect _scrollRect;
private RectTransform _content;
private ContentSizeFitter _sizeFitter;
private VerticalLayoutGroup _verticalLayout;
void Start()
{
_scrollRect = GetComponent<ScrollRect>();
_scrollRect.verticalScrollbar.onValueChanged.AddListener(VerticalScrollChanged);
_content = _scrollRect.content;
_verticalLayout = _content.GetComponent<VerticalLayoutGroup>();
_sizeFitter = _content.GetComponent<ContentSizeFitter>();
VerticalScrollChanged(_scrollRect.verticalScrollbar.value);
}
private void VerticalScrollChanged(float value)
{
float childCount = _content.childCount;
float valueY = Mathf.Clamp01(value);
_sizeFitter.enabled = false; // I'm not sure, but I hope this blocks the parent size recalculation and ...
for (int i = 0; i < childCount; i++)
{
float factor = 1f - (i / (childCount - 1));
float lerpValue = 1f - Math.Abs(factor - valueY);
_content.GetChild(i).localScale = Vector3.one * Mathf.Lerp(MinScale, MaxScale, ScaleCurve.Evaluate(lerpValue));
}
_sizeFitter.enabled = true; // ... recalculates the size only after all its children's changes
_sizeFitter.SetLayoutVertical();
_verticalLayout.CalculateLayoutInputVertical();
_verticalLayout.SetLayoutVertical();
}
}