Position UI Images at distance to the center.

Hey guys!

I need to position multiples UI Images at a distance from the center of another UI Image like a clock hands.
Each of these images has a determinated rotation.

radial hosted at ImgBB — ImgBB <<<---- Example :wink:

Thank you so much!

If you’re making something like a clock, it’s probably smarter to create an empty game object at the center of the clock, make your “clock hand” be a child of that, and then move the hand by rotating the empty object. Then at runtime you only need to mess with rotation, instead of rotation and position.

But if for some reason you want to do it all with math, it’s basic trigonometry. Position the image at

clockCenter + desiredDistance * new Vector2(Mathf.Cos(desiredAngle), Mathf.Sin(desiredAngle))

Thanks for answering!
I have tried to follow your steps but I see that I have done something wrong.

radial-2 hosted at ImgBB — ImgBB <<<-----

  Vector2 pos(GameObject go)
    {
        Vector2 clock_center = transform.position * offset;
        Vector2 v2 = new Vector2(Mathf.Cos(go.transform.rotation.z), Mathf.Sin(go.transform.rotation.z));
        Vector2 v3 = clock_center * v2;

        return dir3;

    }

go.transform.localPosition = pos(go);

I see at least two problems:

  1. “transform.rotation.z” does not mean what you think it means. Transform.rotation is a Quaternion. You are probably thinking of Transform.eulerAngles.

  2. In the equation I gave you, you have replaced the addition with a multiplication.

I’m also pretty suspicious about the fact that you use the script’s absolute position as the center point for calculating the local position for the object you are setting. I’m not sure how your object hierarchy is arranged, but that seems unlikely to be correct.

1 Like

I’ve been with this for a long time and I’m very bad at math.:frowning:
Could you write me an example please?

I did write you an example (for the math)–last line of my first reply. I can’t write an example of how to calculate the values to plug into that equation because those come from the rest of your program, and will depend on how you’ve structured the rest of your program and how you want this code to interact with the rest of your program.

I also started by suggesting an alternative option that wouldn’t require you to do this particular math at all.

Hello again.
I have tried this but the result is not what I expected.

radial-3 hosted at ImgBB — ImgBB <---------

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class prueba_menu_radial : MonoBehaviour
{

    public GameObject button;//UI image portion
    public int button_number = 5;
    public float offset = 3f;//offset of the center

    // Start is called before the first frame update
    void Start()
    {
        for(int i = 0; i < button_number; i++)
        {
            GameObject bt = Instantiate(button);
            bt.transform.SetParent(transform, false);
            bt.transform.rotation = Quaternion.Euler(0, 0, ((360f / button_number) * i) - 45f);//radial rotation
            bt.transform.localPosition = position_b(bt);//<<----- position around the clock with offset
        }
    }

    Vector2 position_b(GameObject bt)
    {
        // center of the clock
        Vector2 clock_center = transform.localPosition;

        // center of the clock + offset
        Vector2 v1 = new Vector2(clock_center.x + offset, clock_center.y + offset);

        // rotation of the button to vector2???
        Vector2 v2 = new Vector2(Mathf.Cos(bt.transform.eulerAngles.z), Mathf.Sin(bt.transform.eulerAngles.z));

        Vector2 v3 = v1 * v2;
       
        return v3;
    }
  
}

Reminder: multiplication comes before addition. You want to multiply the trig stuff by the offset length and then add the clock center. The center should not be multiplied by anything at any point, directly or indirectly.

(You could seriously take the exact equation I wrote and copy-paste that into your code. You’d just need to change the variable names to match.)

Protip: Pay attention to whether a Vector3 conceptually represents a position or an offset. You can multiply an offset by something, but you should never ever multiply a position by anything.

clockCenter + desiredDistance * new Vector2(Mathf.Cos(desiredAngle), Mathf.Sin(desiredAngle))

desiredDistance is a float or a vector? I cant add clockCenter(vector) + desiredDistance(float)…

desiredDistance is a float. You are still doing the operations in the wrong order.

vector + float * vector
means that first you do (float * vector), which gives you a vector, and then you do (vector + vector)

1 Like

Ahhhh ok thank you!