Skip to content

Commit ea3b695

Browse files
committed
UI Changes
1 parent 0822e1a commit ea3b695

2 files changed

Lines changed: 149 additions & 8 deletions

File tree

Packages/net.pawlygon.unitytools/Editor/AvatarSetupWizard.cs

Lines changed: 148 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ public class AvatarSetupWizard : EditorWindow
2323
private const string VrcftPrefabGuid = "ca618adb2c3333545a1f36d72a73a3ef";
2424
private const string VrcftPackageListingUrl = "https://vcc.pawlygon.net/";
2525
private const string PatcherHubLatestReleaseApiUrl = "https://api.github.com/repos/PawlygonStudio/PatcherHub/releases/latest";
26+
private const string PawlygonWebsiteUrl = "https://www.pawlygon.net";
27+
private const string PawlygonTwitterUrl = "https://x.com/Pawlygon_studio";
28+
private const string PawlygonYouTubeUrl = "https://www.youtube.com/@Pawlygon";
29+
private const string PawlygonDiscordUrl = "https://discord.com/invite/pZew3JGpjb";
30+
private const string PackageJsonPath = "Packages/net.pawlygon.unitytools/package.json";
31+
private const int SourceFbxPickerControlId = 9001;
32+
private const int SourcePrefabPickerControlId = 9002;
2633

2734
[SerializeField] private string mainFolderName = DefaultMainFolderName;
2835
[SerializeField] private bool useSeparateFolderPerAvatar;
@@ -41,6 +48,7 @@ public class AvatarSetupWizard : EditorWindow
4148
private string patcherHubImportStatusMessage = string.Empty;
4249
private bool patcherHubImportedThisSession;
4350
private Texture2D pawlygonLogoTexture;
51+
private string packageVersion = "1.0.0";
4452
private GUIStyle sectionStyle;
4553
private GUIStyle titleStyle;
4654
private GUIStyle stepStyle;
@@ -49,6 +57,8 @@ public class AvatarSetupWizard : EditorWindow
4957
private GUIStyle richMiniLabelStyle;
5058
private GUIStyle headerTitleStyle;
5159
private GUIStyle headerSubtitleStyle;
60+
private GUIStyle footerStyle;
61+
private GUIStyle footerLinkStyle;
5262

5363
private enum WizardStep
5464
{
@@ -114,6 +124,12 @@ private class GitHubReleaseAsset
114124
public string browser_download_url;
115125
}
116126

127+
[Serializable]
128+
private class PackageManifestInfo
129+
{
130+
public string version;
131+
}
132+
117133
[MenuItem("!Pawlygon/Avatar Setup Wizard")]
118134
public static void ShowWindow()
119135
{
@@ -126,6 +142,7 @@ private void OnEnable()
126142
{
127143
FBXImportDetector.FbxReimported += HandleFbxReimported;
128144
EnsureAtLeastOneEntry();
145+
LoadPackageVersion();
129146
}
130147

131148
private void OnDisable()
@@ -138,6 +155,7 @@ private void OnGUI()
138155
{
139156
EnsureStyles();
140157
EnsureAtLeastOneEntry();
158+
HandleObjectPickerSelection();
141159

142160
DrawHeader();
143161
DrawStepIndicator();
@@ -167,6 +185,9 @@ private void OnGUI()
167185
EditorGUILayout.Space();
168186
EditorGUILayout.HelpBox(statusMessage, MessageType.Info);
169187
}
188+
189+
EditorGUILayout.Space(8f);
190+
DrawFooter();
170191
}
171192

172193
private void DrawSetupStep()
@@ -259,8 +280,8 @@ private void DrawAvatarEntryEditor(int index, AvatarEntry entry)
259280
}
260281
}
261282

262-
entry.sourceFbx = (GameObject)EditorGUILayout.ObjectField("Source FBX", entry.sourceFbx, typeof(GameObject), false);
263-
entry.sourcePrefab = (GameObject)EditorGUILayout.ObjectField("Source Prefab", entry.sourcePrefab, typeof(GameObject), false);
283+
entry.sourceFbx = DrawFilteredAssetField("Source FBX", entry.sourceFbx, "fbx", SourceFbxPickerControlId + index * 2);
284+
entry.sourcePrefab = DrawFilteredAssetField("Source Prefab", entry.sourcePrefab, "prefab", SourcePrefabPickerControlId + index * 2);
264285

265286
if (useSeparateFolderPerAvatar)
266287
{
@@ -1726,6 +1747,66 @@ private static void DrawReadOnlyPathField(string label, string value)
17261747
}
17271748
}
17281749

1750+
private GameObject DrawFilteredAssetField(string label, GameObject currentValue, string extension, int controlId)
1751+
{
1752+
Rect totalRect = EditorGUILayout.GetControlRect();
1753+
Rect fieldRect = EditorGUI.PrefixLabel(totalRect, new GUIContent(label));
1754+
1755+
Event currentEvent = Event.current;
1756+
if (currentEvent.type == EventType.MouseDown && fieldRect.Contains(currentEvent.mousePosition))
1757+
{
1758+
bool clickedPickerButton = currentEvent.mousePosition.x >= fieldRect.xMax - 19f;
1759+
if (clickedPickerButton)
1760+
{
1761+
EditorGUIUtility.ShowObjectPicker<GameObject>(currentValue, false, $"glob:\"*.{extension}\"", controlId);
1762+
currentEvent.Use();
1763+
}
1764+
}
1765+
1766+
return (GameObject)EditorGUI.ObjectField(fieldRect, GUIContent.none, currentValue, typeof(GameObject), false);
1767+
}
1768+
1769+
private void HandleObjectPickerSelection()
1770+
{
1771+
Event currentEvent = Event.current;
1772+
if (currentEvent.type != EventType.ExecuteCommand && currentEvent.type != EventType.ValidateCommand)
1773+
{
1774+
return;
1775+
}
1776+
1777+
if (currentEvent.commandName != "ObjectSelectorUpdated" && currentEvent.commandName != "ObjectSelectorClosed")
1778+
{
1779+
return;
1780+
}
1781+
1782+
int pickerControlId = EditorGUIUtility.GetObjectPickerControlID();
1783+
UnityEngine.Object pickedObject = EditorGUIUtility.GetObjectPickerObject();
1784+
if (pickedObject is not GameObject pickedGameObject)
1785+
{
1786+
return;
1787+
}
1788+
1789+
string assetPath = AssetDatabase.GetAssetPath(pickedGameObject);
1790+
string extension = Path.GetExtension(assetPath);
1791+
1792+
for (int i = 0; i < avatarEntries.Count; i++)
1793+
{
1794+
if (pickerControlId == SourceFbxPickerControlId + i * 2 && string.Equals(extension, ".fbx", StringComparison.OrdinalIgnoreCase))
1795+
{
1796+
avatarEntries[i].sourceFbx = pickedGameObject;
1797+
Repaint();
1798+
return;
1799+
}
1800+
1801+
if (pickerControlId == SourcePrefabPickerControlId + i * 2 && string.Equals(extension, ".prefab", StringComparison.OrdinalIgnoreCase))
1802+
{
1803+
avatarEntries[i].sourcePrefab = pickedGameObject;
1804+
Repaint();
1805+
return;
1806+
}
1807+
}
1808+
}
1809+
17291810
private void EnsureStyles()
17301811
{
17311812
if (sectionStyle != null)
@@ -1761,6 +1842,22 @@ private void EnsureStyles()
17611842
? new Color(0.72f, 0.72f, 0.72f)
17621843
: new Color(0.35f, 0.35f, 0.35f);
17631844

1845+
footerStyle = new GUIStyle(EditorStyles.label)
1846+
{
1847+
alignment = TextAnchor.MiddleCenter,
1848+
fontSize = 11
1849+
};
1850+
1851+
footerLinkStyle = new GUIStyle(EditorStyles.label)
1852+
{
1853+
alignment = TextAnchor.MiddleCenter,
1854+
fontSize = 11,
1855+
stretchWidth = false
1856+
};
1857+
1858+
footerLinkStyle.normal.textColor = new Color(0.39f, 0.67f, 1f);
1859+
footerLinkStyle.hover.textColor = new Color(0.58f, 0.79f, 1f);
1860+
17641861
stepStyle = new GUIStyle(EditorStyles.miniLabel)
17651862
{
17661863
alignment = TextAnchor.MiddleCenter,
@@ -1800,11 +1897,12 @@ private void DrawHeader()
18001897

18011898
float logoSize = 70f;
18021899
float spacing = 16f;
1803-
float totalWidth = logoSize + spacing + 360f;
1900+
float textBlockWidth = Mathf.Min(520f, Mathf.Max(300f, headerRect.width - 140f));
1901+
float totalWidth = logoSize + spacing + textBlockWidth;
18041902
float startX = headerRect.x + Mathf.Max(0f, (headerRect.width - totalWidth) * 0.5f);
18051903
float logoY = headerRect.y + (headerRect.height - logoSize) * 0.5f;
18061904
float textX = startX + logoSize + spacing;
1807-
float textWidth = Mathf.Max(220f, headerRect.xMax - textX - 20f);
1905+
float textWidth = textBlockWidth;
18081906

18091907
if (pawlygonLogoTexture != null)
18101908
{
@@ -1814,14 +1912,57 @@ private void DrawHeader()
18141912
EditorGUI.LabelField(new Rect(textX, headerRect.y + 18f, textWidth, 22f), "Pawlygon Avatar Setup Wizard", headerTitleStyle);
18151913
EditorGUI.LabelField(new Rect(textX, headerRect.y + 40f, textWidth, 36f), "Tool to duplicate avatars, prepare face tracking assets, and build ready-to-edit prefabs.", headerSubtitleStyle);
18161914

1817-
EditorGUILayout.Space(10f);
1818-
Rect separatorRect = EditorGUILayout.GetControlRect(false, 1f);
1819-
EditorGUI.DrawRect(separatorRect, EditorGUIUtility.isProSkin ? new Color(0.34f, 0.34f, 0.34f) : new Color(0.65f, 0.65f, 0.65f));
18201915
}
18211916

18221917
EditorGUILayout.Space(6f);
18231918
}
18241919

1920+
private void DrawFooter()
1921+
{
1922+
using (new EditorGUILayout.VerticalScope(new GUIStyle(EditorStyles.helpBox) { padding = new RectOffset(12, 12, 10, 10) }))
1923+
{
1924+
EditorGUILayout.LabelField($"Made with ❤ by Pawlygon Studio • v{packageVersion}", footerStyle);
1925+
EditorGUILayout.Space(6f);
1926+
1927+
using (new EditorGUILayout.HorizontalScope())
1928+
{
1929+
GUILayout.FlexibleSpace();
1930+
DrawFooterLink("Website", PawlygonWebsiteUrl);
1931+
GUILayout.Space(28f);
1932+
DrawFooterLink("X (Twitter)", PawlygonTwitterUrl);
1933+
GUILayout.Space(28f);
1934+
DrawFooterLink("YouTube", PawlygonYouTubeUrl);
1935+
GUILayout.Space(28f);
1936+
DrawFooterLink("Discord", PawlygonDiscordUrl);
1937+
1938+
GUILayout.FlexibleSpace();
1939+
}
1940+
}
1941+
}
1942+
1943+
private void DrawFooterLink(string label, string url)
1944+
{
1945+
if (GUILayout.Button(label, footerLinkStyle))
1946+
{
1947+
Application.OpenURL(url);
1948+
}
1949+
}
1950+
1951+
private void LoadPackageVersion()
1952+
{
1953+
TextAsset packageJson = AssetDatabase.LoadAssetAtPath<TextAsset>(PackageJsonPath);
1954+
if (packageJson == null || string.IsNullOrWhiteSpace(packageJson.text))
1955+
{
1956+
return;
1957+
}
1958+
1959+
PackageManifestInfo manifestInfo = JsonUtility.FromJson<PackageManifestInfo>(packageJson.text);
1960+
if (!string.IsNullOrWhiteSpace(manifestInfo?.version))
1961+
{
1962+
packageVersion = manifestInfo.version;
1963+
}
1964+
}
1965+
18251966
private void DrawStepIndicator()
18261967
{
18271968
using (new EditorGUILayout.HorizontalScope(new GUIStyle(EditorStyles.helpBox) { padding = new RectOffset(5, 5, 5, 5) }))

Packages/net.pawlygon.unitytools/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "net.pawlygon.unitytools",
3-
"version": "1.1.0",
3+
"version": "1.3.0",
44
"displayName": "Pawlygon - Unity Tools",
55
"description": "Pawlygon tools for Unity. A collection of tools and utilities for VRChat avatar creation and development.",
66
"unity": "2022.3",

0 commit comments

Comments
 (0)