Search Unity

AnchorScreenFollow - Need help

Discussion in 'UGUI & TextMesh Pro' started by mimminito, Nov 14, 2014.

  1. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Hey,

    So, I've created a script to anchor some content to either its parents edge, or a pre-defined position depending on where the content is.
    For example, I am using this in a ScrollRect, so that a label is always anchored to the right edge of the screen unless its greater than the parents width. Here are a couple of screenshots to explain:

    Anchored to the right edge of the screen
    Screen Shot 2014-11-14 at 15.46.49.png
    Anchored to the right edge of the parent when the scrolled past
    Screen Shot 2014-11-14 at 15.46.56.png

    For the most part this works great. But there is some jittering between positions when the inertia is being applied to the ScrollRect and you scroll again.

    Im hoping someone can help out and fix this issue with me. I am still looking into it, but thought id share it with the community to use with the hope we can fix and improve it along the way.

    Hopefully someone finds this useful.

    Here is the code (the script is also attached):
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class AnchorScreenFollow : MonoBehaviour
    6. {
    7.  
    8.     #region Enums
    9.  
    10.     public enum ScreenAnchorPoint
    11.     {
    12.         Left,
    13.         Right,
    14.         Center
    15.     }
    16.  
    17.     #endregion
    18.  
    19.     #region Public Variables
    20.  
    21.     public Canvas _Canvas;
    22.     public RectTransform _TargetRectTransform;
    23.     public RectTransform _ParentAnchorRectTransform;
    24.     public ScreenAnchorPoint _ScreenAnchorPoint;
    25.     public float _ScreenAnchorPadding = 0f;
    26.     public float _CenterTolerance = 2f;
    27.     public float _SmoothTime = 0.5f;
    28.     public float _EdgeAnchorPadding = 0f;
    29.  
    30.     #endregion
    31.  
    32.     #region Private Variables
    33.  
    34.     private bool mIsDragging = false;
    35.     private float mAnchorXPos;
    36.     private bool mHasSetup = false;
    37.     private float mHalfWidth;
    38.  
    39.     #endregion
    40.  
    41.     #region Unity Methods
    42.  
    43.     void Start ()
    44.     {
    45.         StartCoroutine (Setup ());
    46.     }
    47.  
    48.     void Update ()
    49.     {
    50.         if (mHasSetup) {
    51.             UpdatePosition (false);
    52.         }
    53.     }
    54.  
    55.     #endregion
    56.  
    57.     #region Public Methods
    58.  
    59.     public void SetIsDragging (bool isDragging)
    60.     {
    61.         mIsDragging = isDragging;
    62.     }
    63.  
    64.     #endregion
    65.  
    66.     #region Private Methods
    67.  
    68.     private IEnumerator Setup ()
    69.     {
    70.         yield return new WaitForEndOfFrame ();
    71.  
    72.         mHalfWidth = (_TargetRectTransform.rect.width * _Canvas.scaleFactor) / 2;
    73.  
    74.         switch (_ScreenAnchorPoint) {
    75.         case ScreenAnchorPoint.Left:
    76.             mAnchorXPos = mHalfWidth + _ScreenAnchorPadding;
    77.             break;
    78.         case ScreenAnchorPoint.Right:
    79.             mAnchorXPos = Screen.width - mHalfWidth + (-_ScreenAnchorPadding);
    80.             break;
    81.         case ScreenAnchorPoint.Center:
    82.             mAnchorXPos = (Screen.width / 2) + _ScreenAnchorPadding;
    83.             break;
    84.         }
    85.  
    86.         UpdatePosition (true);
    87.  
    88.         mHasSetup = true;
    89.     }
    90.  
    91.     private void UpdatePosition (bool forceMove)
    92.     {
    93.         // Grab the current position
    94.         Vector3 newPos = _TargetRectTransform.position;
    95.  
    96.         newPos.x = mAnchorXPos;
    97.  
    98.         // Update our position
    99.         _TargetRectTransform.position = newPos;
    100.  
    101.         // Check to see if we are outside the parent, and if we are bring ourselves back in
    102.         float textLeftPos = (_TargetRectTransform.anchoredPosition.x - (_TargetRectTransform.rect.width / 2)) - _EdgeAnchorPadding;
    103.         float parentLeftPos = -_ParentAnchorRectTransform.rect.width / 2;
    104.         float textRightPos = (_TargetRectTransform.anchoredPosition.x + (_TargetRectTransform.rect.width / 2)) + _EdgeAnchorPadding;
    105.         float parentRightPos = _ParentAnchorRectTransform.rect.width / 2;
    106.  
    107.         if (textLeftPos < parentLeftPos) {
    108.             _TargetRectTransform.localPosition = new Vector3 (_ParentAnchorRectTransform.rect.x + (_TargetRectTransform.rect.width / 2) + _EdgeAnchorPadding, _ParentAnchorRectTransform.rect.height / 2, 0);
    109.         } else if (textRightPos > parentRightPos) {
    110.             _TargetRectTransform.localPosition = new Vector3 (_ParentAnchorRectTransform.rect.width - (_TargetRectTransform.rect.width / 2) - _EdgeAnchorPadding, _ParentAnchorRectTransform.rect.height / 2, 0);
    111.         }
    112.     }
    113.  
    114.     #endregion
    115. }
    Adam
     

    Attached Files: