public static void ApplyAnchorPreset(this RectTransform rectTransform, TextAnchor presetToApply, bool alsoSetPivot = false, bool alsoSetPosition = false) { Vector2 anchorsToSet = presetToApply.ToViewportCoords(); rectTransform.SetAnchors(anchorsToSet, anchorsToSet); if (alsoSetPivot) { rectTransform.SetPivot(anchorsToSet); } if (alsoSetPosition) { rectTransform.PositionRelativeToParent(anchorsToSet); } }
/// <summary> /// Why wasn't this functionality built-in? /// </summary> /// <param name="rectTransform"></param> /// <param name="presetToApply"></param> /// <param name="alsoSetPivot"></param> /// <param name="alsoSetPosition"></param> public static void ApplyAnchorPreset(this RectTransform rectTransform, TextAnchor presetToApply, bool alsoSetPivot = false, bool alsoSetPosition = false) { // just applying the anchors Vector2 anchorsToApply = presetToApply.ToViewportCoords(); rectTransform.anchorMin = anchorsToApply; rectTransform.anchorMax = anchorsToApply; if (alsoSetPivot) { rectTransform.pivot = anchorsToApply; } if (alsoSetPosition) { rectTransform.PositionRelativeToParent(anchorsToApply); } }
public static void PositionRelativeToParent(this RectTransform rectTransform, TextAnchor preset) { Vector2 vpCoords = preset.ToViewportCoords(); rectTransform.PositionRelativeToParent(vpCoords); }
public static void SetPivot(this RectTransform rectTransform, TextAnchor newPivot) { Vector2 vpCoords = newPivot.ToViewportCoords(); rectTransform.SetPivot(vpCoords); }
/// <summary> /// position - Viewport coords to place this rectTransform with. i.e (0.5, 0.5) places /// this rectTransform at the center of the parent's rect. /// <para/>stayInBounds - self-explanatory. /// </summary> /// <param name="rectTransform"></param> /// <param name="position"></param> /// <param name="stayInBounds"></param> public static void PositionRelativeToParent(this RectTransform rectTransform, TextAnchor position, bool stayInBounds = true) { Vector2 effectivePos = position.ToViewportCoords(); RectTransform parentRect = rectTransform.parent.GetComponent <RectTransform>(); if (parentRect == null) { // So cruel! string errorMessageFormat = "{0}: I don't have any parents! Why would you"; errorMessageFormat += "apply an anchor preset to an orphan, and then tell it"; errorMessageFormat += "to move itself, you sick bastard?!"; throw new ArgumentException(string.Format(errorMessageFormat, rectTransform.name)); } // It's easier to do this by treating the lower left corner as an origin point, // and relocating the rect trans from there Vector2 origin = parentRect.GetLowerLeftCorner(); Vector2 newPos = origin; float xShift = parentRect.rect.width * effectivePos.x; float yShift = parentRect.rect.height * effectivePos.y; newPos += new Vector2(xShift, yShift); // Before we move this rect transform to the lower left corner, we need to set its pivot and // anchors to the center; makes the full reposiitoning easier. // They'll be reverted after the repositioning is fully done. Vector2 originalAnchorMin = rectTransform.anchorMin; Vector2 originalAnchorMax = rectTransform.anchorMax; Vector2 originalPivot = rectTransform.pivot; rectTransform.ApplyAnchorPreset(TextAnchor.MiddleCenter, true, false); rectTransform.localPosition = newPos; if (!stayInBounds) { rectTransform.SetAnchors(originalAnchorMin, originalAnchorMax); rectTransform.pivot = originalPivot; return; } else { // not using the edge-getting extension functions for the following few floats, // since this needs to know the parent's edge coords in the local space of // this rectTransform float parentLeftEdgeX = -parentRect.rect.width * parentRect.pivot.x; float parentRightEdgeX = parentRect.rect.width * (1f - parentRect.pivot.x); float parentUpperEdgeY = parentRect.rect.height * (1f - parentRect.pivot.x); float parentLowerEdgeY = -parentRect.rect.height * parentRect.pivot.y; bool tooFarLeft = rectTransform.LeftEdgeX() < parentLeftEdgeX; bool tooFarRight = rectTransform.RightEdgeX() > parentRightEdgeX; bool tooFarUp = rectTransform.UpperEdgeY() > parentUpperEdgeY; bool tooFarDown = parentLowerEdgeY > rectTransform.LowerEdgeY(); float howFarOff; float leftEdgeDistance = (parentLeftEdgeX - rectTransform.LeftEdgeX()); float rightEdgeDistance = (rectTransform.RightEdgeX() - parentRightEdgeX); float upperEdgeDistance = rectTransform.UpperEdgeY() - parentUpperEdgeY; float lowerEdgeDistance = parentLowerEdgeY - rectTransform.LowerEdgeY(); if (tooFarLeft) { howFarOff = leftEdgeDistance * (1f - effectivePos.x); rectTransform.localPosition += new Vector3(howFarOff, 0, 0); } if (tooFarRight) { howFarOff = rightEdgeDistance * effectivePos.x; rectTransform.localPosition -= new Vector3(howFarOff, 0, 0); } if (tooFarUp) { howFarOff = upperEdgeDistance * effectivePos.y; rectTransform.localPosition -= new Vector3(0, howFarOff, 0); } if (tooFarDown) { howFarOff = lowerEdgeDistance * (1f - effectivePos.y); rectTransform.localPosition += new Vector3(0, howFarOff, 0); } } // We're done! Revert the anchors. rectTransform.SetAnchors(originalAnchorMin, originalAnchorMax); rectTransform.pivot = originalPivot; }