在編輯器中,通過設置Raw edit mode,可以切換兩種,元素錨點的改變模式:
- 一種是錨點單獨改變,即:不開啟原始模式,保持原樣,改變anchoredPosition與sizeDelta。
- 一種是錨點聯動顯示,即:開啟原始模式,不保持原樣,不改變anchoredPosition與sizeDelta。
原理很簡單,anchoredPosition與sizeDelta都是相對于錨點Anchor的,所以Anchor變動,元素rect保持原樣,就需要改變pos和delta,而元素rect跟著變動,就可以維持pos和delta不變。
那么,在運行時用代碼設置anchorMin與anchorMax,只有聯動顯示的模式,即相當于開啟原始模式——不改變anchoredPosition與sizeDelta,改變元素rect的顯示。
但有時候,我們需要只改變錨點,而保持rect顯示不變——這是利用錨點適配不同分辨率后的結果——這樣其父類的改變,就可以不影響子類的縮放,如:將子類錨點設置為中心點。
解決方案,就是用offsetMin與offsetMax,來反向抵消anchorMin與anchorMax的變化,從而維持元素rect的顯示不變。
代碼實現如下:
/// <summary>
/// Set the anchorMin [v2] without changing the [rectTransform] display.
/// Assume [rectTransform] has a parent, because the root is rarely operated on.
/// </summary>
public static void SetAnchorMinOnly(this RectTransform rectTransform, in Vector2 v2)
{var offsetOriginal = rectTransform.anchorMin - v2;if (offsetOriginal == Vector2.zero){Debug.LogWarning($"[SetAnchorMinOnly]: The [v2 = {v2}] is the same as the [anchorMin].");return;}else if (offsetOriginal.x == 0.0f){Debug.LogWarning($"[SetAnchorMinOnly]: The [v2.x = {v2.x}] is the same as the [anchorMin.x].");rectTransform.SetAnchorMinYOnly(v2.y);return;}else if (offsetOriginal.y == 0.0f){Debug.LogWarning($"[SetAnchorMinOnly]: The [v2.y = {v2.y}] is the same as the [anchorMin.y].");rectTransform.SetAnchorMinXOnly(v2.x);return;}rectTransform.anchorMin = v2;var parentSize = (rectTransform.parent as RectTransform).rect.size;rectTransform.offsetMin = parentSize * offsetOriginal;
} /// <summary>
/// Set the anchorMax [v2] without changing the [rectTransform] display.
/// Assume [rectTransform] has a parent, because the root is rarely operated on.
/// </summary>
public static void SetAnchorMaxOnly(this RectTransform rectTransform, in Vector2 v2)
{var offsetOriginal = rectTransform.anchorMax - v2;if (offsetOriginal == Vector2.zero){Debug.LogWarning($"[SetAnchorMaxOnly]: The [v2 = {v2}] is the same as the [anchorMax].");return;}else if (offsetOriginal.x == 0.0f){Debug.LogWarning($"[SetAnchorMaxOnly]: The [v2.x = {v2.x}] is the same as the [anchorMax.x].");rectTransform.SetAnchorMaxYOnly(v2.y);return;}else if (offsetOriginal.y == 0.0f){Debug.LogWarning($"[SetAnchorMaxOnly]: The [v2.y = {v2.y}] is the same as the [anchorMax.y].");rectTransform.SetAnchorMaxXOnly(v2.x);return;}rectTransform.anchorMax = v2;var parentSize = (rectTransform.parent as RectTransform).rect.size;rectTransform.offsetMax = parentSize * offsetOriginal;
}