Search code examples
c#unity-game-engine

How to calculate the prefab scale size to fit automatic to a ui slider height?


In the method CreateMarks i create marks on a ui slider and then set the marks size to fit it on the slider height. but instead settings the size manual i want to set it automatically.

void CreateMarks()
{
    RectTransform sliderRect = slider.GetComponent<RectTransform>();

    // Calculate the width of each step on the slider
    float stepWidth = sliderRect.rect.width / (objectsToMove.Count + 1); // +1 to avoid overlapping at edges

    for (int i = 1; i <= objectsToMove.Count; i++)
    {
        // Instantiate a mark
        // Find the Handle Slide Area within the slider
        Transform handleSlideArea = slider.transform.Find("Handle Slide Area");

        // Instantiate the prefab as a child of the Handle Slide Area
        GameObject mark = Instantiate(markPrefab, handleSlideArea);

        SetMarKSize(mark, sliderRect.rect.height);

        // Set the sibling index of the instantiated prefab to be before the Handle
        // Assuming "Handle" is the last child, we place mark before it
        mark.transform.SetSiblingIndex(handleSlideArea.childCount - 2);

        RectTransform markRect = mark.GetComponent<RectTransform>();

        // Position the mark at the corresponding step position
        markRect.anchoredPosition = new Vector2(stepWidth * i - (sliderRect.rect.width / 2), 0);
        marks.Add(mark);
    }
}

private void SetMarKSize(GameObject mark, float size)
{
    mark.transform.localScale = new Vector3(size * 0.01f, size * 0.01f, 1);
}

this screenshot show the marks after changing them with the script.

I know that in this case example the slider height is 20 so * 0.01 it's making each mark object scale 0.2 on the x and y.

i know that 0.1 is the right scale. but i don't want to make it manual i want that no matter what size i change the slider the marks will fit automatically.

the slider settings

mark settings


Solution

  • In general you should try to avoid using the scale for UI Elements and rather adjust the width and height accordingly

    You currently do * 0.01 because your Image prefab has width and height 100 ;)

    So your 100 * 0.2 comes just back to the desired 20.

    Instead I think you could rather just set the RectTransform.sizeDelta to the expected

    mark.GetComponent<RectTransform>().sizeDelta = Vector2.one * size;
    

    In your case this should work as the Images use non stretched anchoring. More general would be using SetSizeWithCurrentAnchors

    Alternatively you could probably also use stretched anchors and make your Images height fit the slider and use preserve Aspect to keep the same width as well as the Knob texture you use is a square