Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do you set a RectTransform.anchoredPosition to match another RectTransform.anchoredPosition?

Discussion in 'Scripting' started by Disastercake, Apr 23, 2018.

  1. Disastercake

    Disastercake

    Joined:
    Apr 7, 2012
    Posts:
    317
    I'm having difficulty figuring out (using overlay canvas) how to set the position of a RectTransform to match another RectTransform, essentially placing them on top of each other. The objects have different parents/anchors, and therefore their anchoredPosition variables work differently.

    I use to do this with just

    Code (CSharp):
    1. RectTransform1.position = RectTransform2.position;
    but this no longer seems to actually move RectTransform1. I'm not sure if this was a change somewhere on my end, or a Unity update at some point (it's been broken for quite a while now, but did work at one point flawlessly).

    My goal is to get a cursor object to appear next to my buttons when they are hovered over or selected with a controller (like a traditional console game would do).

    Any idea on how to deal with matching anchoredPosition on two different RectTransform's?

     
    Last edited: Apr 23, 2018
  2. Disastercake

    Disastercake

    Joined:
    Apr 7, 2012
    Posts:
    317
    After a couple days of testing and trying to repro the bug, I finally discovered that the "Aspect Ratio Fitter" component is currently bugged out and preventing RectTransform being moved by anything other than its anchoredPosition.

    Aspect Ratio Fitter
    https://docs.unity3d.com/Manual/script-AspectRatioFitter.html

    Removing it from the Canvas object works perfectly, but it's required that my game have a specific aspect ratio... I guess I'll just report it and pray to the Unity gods that it gets fixed before I have to release.
     
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    In the example I'm assuming you're talking about the yellow thing with the blue orbs and wings? Any reason you can't just parent it to the button (temporarily) and then offset its local position? That may be a workaround for the issue you're having.
     
  4. Disastercake

    Disastercake

    Joined:
    Apr 7, 2012
    Posts:
    317
    That's actually exactly what I'm doing now for the UI elements as a fix, but it still prevents me from setting the position over game world objects (like selecting an enemy in combat). There's other options for that (like a 3D arrow model to instead of the canvas UI), but it'd just be really cool if Unity is able to fix the bug instead of having to do these hacky work-arounds.
     
  5. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    All anchored position is, is the offset of the RectTransform local position of its pivot from the local position of its anchor (assuming all four anchors are together, otherwise I think it uses the average of the 4 points). so if the anchor is the bottom-left corner and the pivot is in the center, then the anchored position is simply half the size of the RectTransform.rect.size.

    so what you can do is get the button's transform position (world space) and convert it into the cursor's local space (as targetPosition). Convert your anchors into a local space by averaging anchorMin and anchorMax and multiplying them with the rect.size of the parent (as localAnchorPosition). Now, your cursor's rectTransform.anchoredPosition should simply be targetPosition - localAnchoredPosition.

    Of course the origin of a RectTransform is the center of the transform (not the bottom left as the math says, regardless of anchor/pivot positions) so the vector math should have subtracted half of the rect size first, but since both localAnchoredPosition and targetPosition would have to make that subtraction and then get subtracted together that offset actually gets canceled out so we don't have to math for it.

    To summarize (granted I didn't test this):

    Code (CSharp):
    1. var targetPosition = cursor.InverseTransformPoint(targetButton.position);
    2. var rt= cursor.parent as RectTransform;
    3. if(!rt) rt= cursor;
    4. var localAnchorPosiiton = Vector2.scale(
    5. (cursor.anchorMax + cursor.anchorMin)*0.5f,
    6. rt.rect.size
    7. );
    8.  
    9.  
    10. cursor.anchoredPosition = targetPosition  - localAnchorPosiiton ;
    then you should be able to shift around your cursor's pivot and anchor to get the proper offset you're looking for. I assume you'd want the the cursor's anchors be in the center while the pivot would be off to the right outside the spite's bounds where you'll assume the target button's center would be