- Home /
UI: Positioning an element relative to another element with Scale With screen Size
I'm trying to place a ui element relative to another element. This works perfectly fine as long as my Canvas scaler's Ui Scale mode is: Constant Pixel Size. If I change the mode to Scale with screen size, then the placement if way off.
I'm placing the Second element like this:
secondElementPos = new Vector3(firstElementRect.position.x- firstElementRect.rect.width, firstElementRect.position.y, firstElementRect.position.z);
I know that the problem is that I don't take the screen size into account when I calculate the position. This is a problem because the element always has the same size regardless of the screen size.
So my question is, how do I take the size of the screen into account so that my element will be placed correct on all resolutions with Scale With Screen Size Mode.
Heres is an illustration of the problem:
Try with stretch mode for horizontal and vertical, only for UI canvas. You can handle tabs to do an object UI canvas scalable like you want with screen size.
Hope it Works for you.
Answer by team_eden · Jan 22, 2015 at 07:45 PM
Use the new UI system, and use a slider with stretching anchors.
In fact, as I can probably tell your trying to make some sort of HP style menu bar here, just set the colors/widths, and your set!
Remember to use the Canvas Scaler on scale with screen size mode!
Now to ANSWER your question more directly, you need to place the anchors of these UI Images closer together, the anchors indicate where on the canvas this is RELATIVE to. So if your anchor is shaped like a rectangle, you will get MORE stretch when you resize Horizontally.
In short, place the anchors of these objects near one another. A second method to do this, is to copy the transform of one object, paste it onto the other objects transform, and just move the object slightly. This will copy any anchor information, and will help these to resize in similar fashion.
If the element does indeed need to be the same size on all screen sizes, set the anchors all to 0.5, since a "point" cannot be resized, this will give you a non-scaling object.
Good luck
PS. Dont place UI objects with scripts unless you absolutely have to! Use the UI tools, and set these within the editor.
Answer by Mmmpies · Jan 22, 2015 at 07:48 PM
The easiest way is to drag the anchors to the corners of each object like this:
No matter what scale mode is used the sub panels remain scaled to the parent object.
Bit tricky getting the anchors to the corners, there may be a way to select this but I haven't found it yet.
Best way is to get the anchors close as you can on the first item then 0 out the settings top/bottom/left/right which snaps the panel to the anchors.
Then duplicate the object and drag to the side, with two object snapping the anchors seems a lot easier for some reason.
EDIT
OK if you need to get some kind of ratio to work out how to scale the positioning try this:
private float ScreenWidthDefault = 800;
private float ScreenHeightDefault = 600;
private float ratioWidth;
private float ratioHeight;
// Use this for initialization
void Start () {
Debug.Log (Screen.width + " by " + Screen.height);
ratioWidth = Screen.width / ScreenWidthDefault;
ratioHeight = Screen.height / ScreenHeightDefault;
Debug.Log ("ratioWidth = " + ratioWidth + " ratioHeight = " + ratioHeight);
}
Then multiply the position/scale by the ratio width/height, if bigger than expected that multiplication should increase the size and gaps but if smaller than your expected size it will multiply by a fraction which means it really divides down.
Not seen enough of your code to implement a test though.
Hey, thanks for the answer, I already gave that a try, and I just did it again to make sure. It doesn't solve my problem. The problem isn't the scaling but the position. Becuse I'm using the width of the objects to place the second object. The values of the width doesn't change when unity scales the object to fit the screen size, so I cant use that value to place my object at the correct position. Btw. you can use the Rect transform's Anchor presets to set the achors at the corners :)
So it definitely has to be set via script, O$$anonymous$$ I'll have a think. Oh and thumbs up for answering my question in yours!
Answer by twobob · Jul 16, 2018 at 08:39 AM
@Mmmpies https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/src/d3fc02c4753ff7bc445f6627d4d83adc3801f944/Editor/uGUITools.cs?at=master&fileviewer=file-view-default
Anchors to corners.... et al.
Answer by No_Username_Found · Oct 02, 2021 at 03:03 PM
(I know it's an old post, but Google still leads people here.) The OP's requested functionality is not possible with only Unity settings. You will need some custom code.
You will need an empty Parent UI that will determine the maximum size of Red + Green. This Parent can be set to stretch if desired, and can be resized at any point. Red and Green should be children of the Parent. Red should be anchored on the left, Green should be Anchored on the Right. Red and Green may stretch vertically, but do not set them to stretch horizontally (we will do that in code). With this initial setup if you resize Parent then Green and Red will move to stay at the left and right edges of Parent with a gap in between.
You can access the width of Parent using Parent.rectTransform.rect.width and set the Red to a percent of that size. If Parent is set to stretch then this will return the current width calculated from that stretch.
public class UIResize : MonoBehaviour
{
[Range(0, 1)]
public float redPercent = 0.5f;
public RectTransform redRect;
public RectTransform greenRect;
public RectTransform parentRect;
// Update is called once per frame
void Update()
{
//set the size of the redRect as a percentage of the parent
redRect.sizeDelta = new Vector2(parentRect.rect.width * redPercent, redRect.sizeDelta.y);
//calculate the percentage size of green as 1 - redPercent
// i.e. Red = 90% => Green = 10%
float greenPercent = 1 - redPercent;
//set the size of the greenRect to our calculated percent
greenRect.sizeDelta = new Vector2(parentRect.rect.width * greenPercent, greenRect.sizeDelta.y);
}
}
Be aware that there is a frame delay between when the screen size changes and when UI elements are updated (so if you move this code out of an Update() function you will need to delay by at least 1 frame for everything to display correctly).