8
\$\begingroup\$

I have a game object that creates a keyboard in side of my world canvas. I am working out the offset positions for each key, and appear to be doing that correctly. However, when I set the positions in the actual keys, the values are being offset by anything from 100 - 1000.


This is the basic method I am currently using to set the position:

public void SetDimensions(Vector2 position)
{
    GetComponent<RectTransform>().localPosition = position;     
    Debug.Log(key + ": " + position);
}

I have also tried using .position and .anchoredPosition, as per the somewhat confusing API reference. I have also tried simply referencing transform.localPosition and transform.position. No matter what, the output is exactly the same. The debug output confirms that I am working out the correct local position, but no matter what I do, that is not the value being set to my transform.

Console reports a value of (-127.3, -301.6), but the Inspector reports a value of (-660.358, -842.0745).

As you can see, I have my pivot set to the center; though I think this may have an impact, it certainly should not cause an offset of 400-500.


As per request, this is my main canvas:


What am I doing wrong, or more specifically, how do I set the exact local position of a game object using a RectTransform?

\$\endgroup\$
3
  • \$\begingroup\$ Please note that I am aware that there are built in keyboard functions. The specific purpose of this exercise is to make a keyboard, specifically because I want to. \$\endgroup\$ – Gnemlock Mar 29 '17 at 7:43
  • \$\begingroup\$ Can you also show us your canvas settings? \$\endgroup\$ – DMGregory Mar 29 '17 at 10:05
  • \$\begingroup\$ @DMGregory, added as per request. I realise I didn't expand my anchors, but they are all set to (0,0). \$\endgroup\$ – Gnemlock Mar 29 '17 at 10:43
5
\$\begingroup\$

First of all, ensure you set the parent before setting local position, then, you have two options according to the type of Rect Transform : non-stretching and stretching ones.

For a non-stretching Rect Transform, the position is set most easily by setting the anchoredPosition and the sizeDelta properties. The anchoredPosition specifies the position of the pivot relative to the anchors. The sizeDelta is just the same as the size when there’s no stretching.

Try to do as follow :

RectTransform rt = GetComponent<RectTransform>();
rt.anchoredPosition = position ;
Debug.Log( position + " " + rt.anchoredPosition ) ;

I've just tried the previous code with a simple button inside a canvas, it works great. If it doesn't for you, you may have another script changing the position or a parent with a Layout group maybe ?


For your information :

For a stretching Rect Transform, it can be simpler to set the position using the offsetMin and offsetMax properties. The offsetMin property specifies the corner of the lower left corner of the rect relative to the lower left anchor. The offsetMax property specifies the corner of the upper right corner of the rect relative to the upper right anchor.

RectTransform rt = GetComponent<RectTransform>();
rt.offsetMin = rt.offsetMax = Vector2.zero ;

Source : https://docs.unity3d.com/Manual/HOWTO-UICreateFromScripting.html

\$\endgroup\$
6
  • \$\begingroup\$ I already tried anchoredPosition, and the offset suggestion does nothing (at least, not in context). \$\endgroup\$ – Gnemlock Mar 29 '17 at 10:40
  • \$\begingroup\$ Maybe the canvas scaler (scale with screen size) interferes with the absolute positioning you are trying to set. \$\endgroup\$ – Hellium Mar 29 '17 at 11:41
  • \$\begingroup\$ Hmm... @Gnemlock, I'm unable to reproduce this error locally. After setting up a UI object and canvas similar to yours, when I set anchoredPosition to my desired position, it updates localPosition to exactly the number I provided (relative, as always, to the anchor - set to be the center of the parent as in your example). Could there be anything else interfering with the expected behaviour here, like additional parents in the hierarchy, special layout containers or other scripts? \$\endgroup\$ – DMGregory Mar 29 '17 at 11:54
  • \$\begingroup\$ I determined the problem to be external. @DMGregory, I had failed to notice that I was setting the parent after setting the position. I feel that the question still has more merit than if I changed it to reflect the actual problem, as it turned out, so I am just going to accept this answer, given that this was how I was setting the exact local position. \$\endgroup\$ – Gnemlock Apr 2 '17 at 9:58
  • \$\begingroup\$ Good find! I'm glad you got it sorted! It may be worth adding "Ensure you set the parent before setting local position" either as its own answer, or to the top of this one, so it has more visibility for future users. I imagine a lot of developers hit this or a flavour of this snag. \$\endgroup\$ – DMGregory Apr 2 '17 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.