Skip to content

Commit 5ede7f0

Browse files
authored
Create RectTransformCloner.cs
1 parent 61f149c commit 5ede7f0

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// clones UI RectTransform values from one GameObject to another in Unity Editor (only for identical hierarchy)
2+
3+
using UnityEngine;
4+
using UnityEditor;
5+
using TMPro;
6+
using UnityEngine.UI;
7+
8+
namespace UnityLibrary.Tools
9+
{
10+
public class RectTransformCloner : EditorWindow
11+
{
12+
private GameObject source;
13+
private GameObject target;
14+
private bool requireIdenticalNames = true;
15+
private bool cloneTMPAlignment = false;
16+
17+
[MenuItem("Tools/RectTransform Cloner")]
18+
private static void ShowWindow()
19+
{
20+
var window = GetWindow<RectTransformCloner>();
21+
window.titleContent = new GUIContent("RectTransform Cloner");
22+
window.Show();
23+
}
24+
25+
private void OnGUI()
26+
{
27+
GUILayout.Label("Clone RectTransform", EditorStyles.boldLabel);
28+
29+
source = (GameObject)EditorGUILayout.ObjectField("Source", source, typeof(GameObject), true);
30+
target = (GameObject)EditorGUILayout.ObjectField("Target", target, typeof(GameObject), true);
31+
requireIdenticalNames = EditorGUILayout.Toggle("Require Identical Names", requireIdenticalNames);
32+
cloneTMPAlignment = EditorGUILayout.Toggle("Clone TMP Alignment", cloneTMPAlignment);
33+
34+
if (GUILayout.Button("Clone RectTransforms"))
35+
{
36+
if (source == null || target == null)
37+
{
38+
Debug.LogError("Source and Target must be assigned.");
39+
return;
40+
}
41+
42+
string errorMessage;
43+
if (!CompareHierarchies(source.transform, target.transform, out errorMessage))
44+
{
45+
Debug.LogError("Source and Target hierarchies do not match!\n" + errorMessage, target);
46+
return;
47+
}
48+
49+
Undo.RegisterFullObjectHierarchyUndo(target, "Clone RectTransform Values");
50+
CopyRectTransforms(source.transform, target.transform);
51+
52+
Debug.Log("RectTransform values cloned successfully.", target);
53+
54+
if (target.transform.parent != null)
55+
{
56+
RectTransform parentRect = target.transform.parent as RectTransform;
57+
if (parentRect != null)
58+
{
59+
LayoutRebuilder.ForceRebuildLayoutImmediate(parentRect);
60+
}
61+
else
62+
{
63+
Debug.LogWarning("Target's parent is not a RectTransform, cannot force layout rebuild.", target);
64+
}
65+
}
66+
else
67+
{
68+
Debug.LogWarning("Target has no parent, cannot force layout rebuild.", target);
69+
}
70+
EditorUtility.SetDirty(target);
71+
SceneView.RepaintAll();
72+
}
73+
}
74+
75+
private bool CompareHierarchies(Transform source, Transform target, out string errorMessage)
76+
{
77+
errorMessage = "";
78+
79+
if (source.childCount != target.childCount)
80+
{
81+
errorMessage = $"Child count mismatch at {GetTransformPath(source)}: Source has {source.childCount}, Target has {target.childCount}";
82+
return false;
83+
}
84+
85+
for (int i = 0; i < source.childCount; i++)
86+
{
87+
var sourceChild = source.GetChild(i);
88+
var targetChild = target.GetChild(i);
89+
90+
if (requireIdenticalNames && sourceChild.name != targetChild.name)
91+
{
92+
errorMessage = $"Child name mismatch at {GetTransformPath(sourceChild)}: Source has '{sourceChild.name}', Target has '{targetChild.name}'";
93+
return false;
94+
}
95+
96+
if (!CompareHierarchies(sourceChild, targetChild, out errorMessage))
97+
{
98+
return false;
99+
}
100+
}
101+
102+
return true;
103+
}
104+
105+
private void CopyRectTransforms(Transform source, Transform target)
106+
{
107+
var sourceRect = source as RectTransform;
108+
var targetRect = target as RectTransform;
109+
110+
if (sourceRect != null && targetRect != null)
111+
{
112+
CopyRectTransformValues(sourceRect, targetRect);
113+
114+
if (cloneTMPAlignment)
115+
{
116+
var sourceTMP = source.GetComponent<TextMeshProUGUI>();
117+
var targetTMP = target.GetComponent<TextMeshProUGUI>();
118+
if (sourceTMP != null && targetTMP != null)
119+
{
120+
Undo.RecordObject(targetTMP, "Clone TMP Alignment");
121+
targetTMP.alignment = sourceTMP.alignment;
122+
}
123+
}
124+
}
125+
126+
for (int i = 0; i < source.childCount; i++)
127+
{
128+
CopyRectTransforms(source.GetChild(i), target.GetChild(i));
129+
}
130+
}
131+
132+
private void CopyRectTransformValues(RectTransform source, RectTransform target)
133+
{
134+
target.anchoredPosition = source.anchoredPosition;
135+
target.sizeDelta = source.sizeDelta;
136+
target.anchorMin = source.anchorMin;
137+
target.anchorMax = source.anchorMax;
138+
target.pivot = source.pivot;
139+
target.localRotation = source.localRotation;
140+
target.localScale = source.localScale;
141+
target.localPosition = source.localPosition;
142+
}
143+
144+
private string GetTransformPath(Transform t)
145+
{
146+
if (t.parent == null)
147+
return t.name;
148+
return GetTransformPath(t.parent) + "/" + t.name;
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)