Search Unity

Child's anchoredPosition to be set based on Canvas (Vector2)

Discussion in 'UGUI & TextMesh Pro' started by karsnen, Jan 21, 2019.

  1. karsnen

    karsnen

    Joined:
    Feb 9, 2014
    Posts:
    65

    • Scenario

      I have a position
      Vector2 targetPosition
      based on the root Canvas of UnityEngine.UI

      Now I want to move a UI Element
      RectTransform ShowButton
      within that Canvas to that targetPosition.
      [URL='https://docs.unity3d.com/ScriptReference/RectTransform.html']RectTransform[/URL].anchoredPosition


      Issue

      This
      ShowButton
      is a child of a RectTransform aligned at center & bottom. Hence the vector2 value of
      ShowButton.anchoredPosition
      is relative to that.

      Request

      Now if I move my
      anchoredPosition
      of
      ShowButton
      , it moves relatively.
      1. How can I convert targetPosition to a relative position of ShowButton (or)
      2. How can I move ShowButton on a global scale (Vector2)?


      Thank you,
      Karsnen
     
  2. karsnen

    karsnen

    Joined:
    Feb 9, 2014
    Posts:
    65
  3. karsnen

    karsnen

    Joined:
    Feb 9, 2014
    Posts:
    65
    SOLUTION

    SPOILER
    : a sort of a hack!

    Steps
    1. Create an empty gameobject (say "locationCalculator") with RectTransform as it's component
    2. Have that gameobject rest under the root canvas
    3. Once you have position (Vector2) relative to the root canvas, set the parent locationCalculator to the RectTransform to which you want to calculate. Also use

      Transform.SetParent (Transform, bool)
      with worldPositionStays as true
    4. Capture the anchoredPosition of locationCalculator. This becomes your target position.
    5. Reset locationCalculator position & parent to normal values (check code)

    Creation of the Gameobject

    Code (CSharp):
    1.    [SerializeField]
    2.         internal RectTransform MyCanvasTransform;
    3.         private RectTransform locationCalculator;
    4.  
    5.         private void Awake()
    6.         {
    7.             if(locationCalculator == null)
    8.             {
    9.                 GameObject _go = new GameObject("locationCalculator");
    10.  
    11.                 locationCalculator = _go.AddComponent<RectTransform>();
    12.                 locationCalculator.SetParent(MyCanvasTransform);
    13.                 _go.transform.localScale = Vector3.one;
    14.                 _go.transform.rotation = Quaternion.identity;
    15.                 _go.transform.position = Vector3.zero;
    16.                 _go.transform.SetAsFirstSibling();
    17.             }
    18.         }


    Getting the target positional values


    Code (CSharp):
    1.         internal Vector2 GetLocal(Vector2 _globalPosition, RectTransform _referenceTransform)
    2.         {
    3.             Vector2 _positionBuffer = _globalPosition;
    4.             locationCalculator.anchoredPosition = _positionBuffer;
    5.             locationCalculator.SetParent(_referenceTransform, true);
    6.  
    7.             _positionBuffer = locationCalculator.anchoredPosition;
    8.             locationCalculator.SetParent(MyCanvasTransform);
    9.             locationCalculator.anchoredPosition = Vector2.zero;
    10.             locationCalculator.SetAsFirstSibling();
    11.             _referenceTransform = null;
    12.  
    13.             return _positionBuffer;
    14.         }

    NOTE

    PLEASE
    note the above solution does not work when & if the RectTransform for which you are figuring position has a size delta of Vector2.zero. It would happen if you stretch to fit.

    Thank you & would like to also any other possible direct solutions.