14 private const string InitialOutputDirectoryName =
"TileGenerator";
15 private const float GUISectionOffset = 10.0f;
16 private const string GUIHorizSpacer =
" ";
17 private const string EditorPrefsKey_AppIcon =
"_EditorPrefsKey_AppIcon";
18 private const string EditorPrefsKey_SplashImage =
"_EditorPrefsKey_SplashImage";
19 private const string EditorPrefsKey_DirectoryName =
"_EditorPrefsKey_DirectoryName";
21 private static string _outputDirectoryName;
22 private static string _originalAppIconPath;
23 private static string _newAppIconPath;
24 private static string _originalSplashImagePath;
25 private static string _newSplashImagePath;
26 private static Texture2D _originalAppIcon;
27 private static Texture2D _originalSplashImage;
28 private static float defaultLabelWidth;
30 [MenuItem(
"Mixed Reality Toolkit/Tile Generator",
false, 9)]
31 private static void OpenWindow()
34 Type inspectorType = Type.GetType(
"UnityEditor.InspectorWindow,UnityEditor.dll");
35 var window = GetWindow<SetIconsWindow>(inspectorType);
36 window.titleContent =
new GUIContent(
"Tile Generator");
37 window.minSize =
new Vector2(320, 256);
41 private void OnEnable()
48 if (!
string.IsNullOrEmpty(_originalAppIconPath))
50 _originalAppIcon = AssetDatabase.LoadAssetAtPath<Texture2D>(_originalAppIconPath);
53 if (!
string.IsNullOrEmpty(_originalSplashImagePath))
55 _originalSplashImage = AssetDatabase.LoadAssetAtPath<Texture2D>(_originalSplashImagePath);
58 if (
string.IsNullOrEmpty(_outputDirectoryName))
60 _outputDirectoryName = Application.dataPath +
"/" + InitialOutputDirectoryName;
63 defaultLabelWidth = EditorGUIUtility.labelWidth;
66 private void OnDisable()
73 GUILayout.Space(GUISectionOffset);
76 GUILayout.Label(
"Images");
79 _originalAppIcon = CreateImageInput(
"App Icon", 1240, 1240, _originalAppIcon, ref _originalAppIconPath);
80 _originalSplashImage = CreateImageInput(
"Splash Image", 2480, 1200, _originalSplashImage, ref _originalSplashImagePath);
82 if (GUILayout.Button(
"Choose Output Folder"))
84 _outputDirectoryName = EditorUtility.OpenFolderPanel(
"Output Folder", Application.dataPath,
"");
88 EditorGUIUtility.labelWidth = 85f;
89 EditorGUILayout.TextField(
"Output folder:", _outputDirectoryName);
90 EditorGUIUtility.labelWidth = defaultLabelWidth;
92 EditorGUILayout.BeginHorizontal();
93 GUILayout.FlexibleSpace();
95 if (GUILayout.Button(
"Update\nIcons", GUILayout.Height(64f), GUILayout.Width(64f)))
97 if (_originalAppIcon == null)
99 EditorUtility.DisplayDialog(
"App Icon not set",
"Please select the App Icon first",
"Ok");
101 else if (_originalSplashImage == null)
103 EditorUtility.DisplayDialog(
"Splash Image not set",
"Please select the Splash Image first",
"Ok");
107 EditorApplication.delayCall += ResizeImages;
111 EditorGUILayout.EndHorizontal();
114 private static void SaveSettings()
121 private static Texture2D CreateImageInput(
string imageTitle,
int width,
int height, Texture2D texture, ref
string path)
123 EditorGUIUtility.labelWidth = 200f;
124 var newIcon = (Texture2D)EditorGUILayout.ObjectField(GUIHorizSpacer + imageTitle +
" (" + width +
"x" + height +
")", texture, typeof(Texture2D),
false);
125 EditorGUIUtility.labelWidth = defaultLabelWidth;
127 if (newIcon == null || newIcon == texture) {
return newIcon; }
129 if (newIcon.width != width && newIcon.height != height)
132 EditorUtility.DisplayDialog(
"Invalid Image",
133 string.Format(
"{0} should be an image with preferred size of {1}x{2}. Provided image was: {3}x{4}.", imageTitle, width, height, newIcon.width, newIcon.height),
139 path = AssetDatabase.GetAssetPath(newIcon);
145 private static void ResizeImages()
149 EditorUtility.DisplayProgressBar(
"Generating images",
"Checking Texture Importers", 0);
152 if (CheckTextureImporter(_originalAppIconPath) || CheckTextureImporter(_originalSplashImagePath))
154 AssetDatabase.Refresh();
157 if (!Directory.Exists(_outputDirectoryName))
159 Directory.CreateDirectory(_outputDirectoryName);
163 foreach (
string file
in Directory.GetFiles(_outputDirectoryName))
170 string outputDirectoryBasePath = _outputDirectoryName;
171 outputDirectoryBasePath = outputDirectoryBasePath.Replace(Application.dataPath,
"Assets");
173 _newAppIconPath = outputDirectoryBasePath +
"/BaseIcon_1240x1240.png";
174 _newSplashImagePath = outputDirectoryBasePath +
"/BaseSplashImage_2480x1200.png";
176 AssetDatabase.CopyAsset(_originalAppIconPath, _newAppIconPath);
177 AssetDatabase.CopyAsset(_originalSplashImagePath, _newSplashImagePath);
180 PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Unknown,
new[] { AssetDatabase.LoadAssetAtPath<Texture2D>(_newAppIconPath) });
181 PlayerSettings.virtualRealitySplashScreen = AssetDatabase.LoadAssetAtPath<Texture2D>(_newSplashImagePath);
184 var types = Enum.GetValues(typeof(PlayerSettings.WSAImageType)).Cast<PlayerSettings.WSAImageType>().ToList();
185 var scales = Enum.GetValues(typeof(PlayerSettings.WSAImageScale)).Cast<PlayerSettings.WSAImageScale>().ToList();
186 float progressTotal = types.Count * scales.Count;
188 bool canceled =
false;
190 foreach (var type
in types)
197 foreach (var scale
in scales)
199 PlayerSettings.WSA.SetVisualAssetsImage(CloneAndResizeToFile(type, scale), type, scale);
202 if (EditorUtility.DisplayCancelableProgressBar(
"Generating images",
string.Format(
"Generating resized images {0} of {1}", progress, progressTotal), progress / progressTotal))
210 AssetDatabase.SaveAssets();
211 AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
215 EditorUtility.DisplayDialog(
"Generation canceled",
216 string.Format(
"{0} Images of {1} were resized and updated in the Player Settings.", progress, progressTotal),
221 EditorUtility.DisplayDialog(
"Images resized!",
222 "All images were resized and updated in the Player Settings",
226 EditorUtility.ClearProgressBar();
230 Debug.LogError(e.Message);
231 EditorUtility.ClearProgressBar();
235 private static bool CheckTextureImporter(
string assetPath)
237 var tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
239 if (tImporter == null || tImporter.isReadable) {
return false; }
241 tImporter.isReadable =
true;
243 AssetDatabase.ImportAsset(assetPath);
247 private static string CloneAndResizeToFile(PlayerSettings.WSAImageType type, PlayerSettings.WSAImageScale scale)
249 string texturePath = GetUWPImageTypeTexture(type, scale);
251 if (
string.IsNullOrEmpty(texturePath)) {
return string.Empty; }
253 var iconSize = GetUWPImageTypeSize(type, scale);
255 if (iconSize == Vector2.zero) {
return string.Empty; }
257 if (iconSize.x == 1240 && iconSize.y == 1240 || iconSize.x == 2480 && iconSize.y == 1200) {
return texturePath; }
259 string filePath =
string.Format(
"{0}/{1}_AppIcon_{2}x{3}.png", _outputDirectoryName, Application.productName, iconSize.x, iconSize.y);
260 filePath = filePath.Replace(Application.dataPath,
"Assets");
262 if (File.Exists(filePath))
270 AssetDatabase.CopyAsset(texturePath, filePath);
271 var clone = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);
275 Debug.LogError(
"Unable to load texture at " + filePath);
283 Color[] pix = clone.GetPixels(0, 0, (
int)iconSize.x, (
int)iconSize.y);
284 clone =
new Texture2D((
int)iconSize.x, (
int)iconSize.y, TextureFormat.ARGB32,
false);
285 clone.SetPixels(pix);
288 var rawData = clone.EncodeToPNG();
289 File.WriteAllBytes(filePath, rawData);
291 if (rawData.Length > 204800)
293 Debug.LogWarningFormat(
"{0} exceeds the minimum file size of 204,800 bytes, please use a smaller image for generating your icons.", filePath);
298 Debug.LogError(e.Message);
305 private static string GetUWPImageTypeTexture(PlayerSettings.WSAImageType type, PlayerSettings.WSAImageScale scale)
309 case PlayerSettings.WSAImageType.PackageLogo:
310 case PlayerSettings.WSAImageType.UWPSquare44x44Logo:
311 case PlayerSettings.WSAImageType.UWPSquare71x71Logo:
312 case PlayerSettings.WSAImageType.UWPSquare150x150Logo:
313 case PlayerSettings.WSAImageType.UWPSquare310x310Logo:
314 return _newAppIconPath;
315 case PlayerSettings.WSAImageType.SplashScreenImage:
316 case PlayerSettings.WSAImageType.UWPWide310x150Logo:
317 if (scale != PlayerSettings.WSAImageScale.Target16 &&
318 scale != PlayerSettings.WSAImageScale.Target24 &&
319 scale != PlayerSettings.WSAImageScale.Target32 &&
320 scale != PlayerSettings.WSAImageScale.Target48 &&
321 scale != PlayerSettings.WSAImageScale.Target256)
323 return _newSplashImagePath;
327 return _newAppIconPath;
330 throw new ArgumentOutOfRangeException(
"type", type, null);
334 private static Vector2 GetUWPImageTypeSize(PlayerSettings.WSAImageType type, PlayerSettings.WSAImageScale scale)
338 case PlayerSettings.WSAImageScale.Target16:
339 return CreateSquareSize(16);
340 case PlayerSettings.WSAImageScale.Target24:
341 return CreateSquareSize(24);
342 case PlayerSettings.WSAImageScale.Target32:
343 return CreateSquareSize(32);
344 case PlayerSettings.WSAImageScale.Target48:
345 return CreateSquareSize(48);
346 case PlayerSettings.WSAImageScale.Target256:
347 return CreateSquareSize(256);
349 return GetWSAImageTypeSize(type, scale);
353 private static Vector2 GetWSAImageTypeSize(PlayerSettings.WSAImageType type, PlayerSettings.WSAImageScale scale)
355 float scaleFactor =
float.Parse(scale.ToString().Replace(
"_",
"")) * 0.01f;
359 case PlayerSettings.WSAImageType.PackageLogo:
360 return CreateSquareSize(50, scaleFactor);
361 case PlayerSettings.WSAImageType.UWPSquare44x44Logo:
362 return CreateSquareSize(44, scaleFactor);
363 case PlayerSettings.WSAImageType.UWPSquare71x71Logo:
364 return CreateSquareSize(71, scaleFactor);
365 case PlayerSettings.WSAImageType.UWPSquare150x150Logo:
366 return CreateSquareSize(150, scaleFactor);
367 case PlayerSettings.WSAImageType.UWPSquare310x310Logo:
368 return CreateSquareSize(310, scaleFactor);
371 case PlayerSettings.WSAImageType.UWPWide310x150Logo:
372 return CreateSize(
new Vector2(310, 150), scaleFactor);
373 case PlayerSettings.WSAImageType.SplashScreenImage:
374 return CreateSize(
new Vector2(620, 300), scaleFactor);
376 Debug.LogWarningFormat(
"Invalid image size for {0} with scale {1}X{2}", type, scale, scaleFactor);
381 private static Vector2 CreateSquareSize(
int size,
float scaleFactor = 1f)
383 var newSize =
new Vector2(size * scaleFactor, size * scaleFactor);
384 newSize.x = (float)Math.Ceiling(newSize.x);
385 newSize.y = (float)Math.Ceiling(newSize.y);
389 private static Vector2 CreateSize(Vector2 size,
float scaleFactor = 1f)
391 var newSize =
new Vector2(size.x * scaleFactor, size.y * scaleFactor);
392 newSize.x = (float)Math.Ceiling(newSize.x);
393 newSize.y = (float)Math.Ceiling(newSize.y);
static void Bilinear(Texture2D tex, int newWidth, int newHeight)