Initial commit
This commit is contained in:
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7e05cf550f12474a9ad1e519d589d8d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94ff83d189e08b444a1e08efea689eba
|
||||
timeCreated: 1659969765
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public enum IconBackground
|
||||
{
|
||||
None,
|
||||
Color,
|
||||
Texture,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90d73a0e6844c524e9c5d71f8a789a63
|
||||
timeCreated: 1674160163
|
||||
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public struct IconBackgroundData
|
||||
{
|
||||
public IconBackground Type { get; }
|
||||
|
||||
public Color Color { get; }
|
||||
public Texture2D Texture { get; }
|
||||
|
||||
public IconBackgroundData(IconBackground type, Color color, Texture2D texture)
|
||||
{
|
||||
Type = type;
|
||||
Color = color;
|
||||
Texture = texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1d0c80f8a67f7747889443725049068
|
||||
timeCreated: 1674290099
|
||||
@@ -0,0 +1,108 @@
|
||||
using System.Linq;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public class IconsCreator
|
||||
{
|
||||
private IconsCreatorData _data;
|
||||
|
||||
private readonly IconsCreatorInternalSceneHandler _sceneHandler;
|
||||
private readonly IconsCreatorCameraUtility _cameraUtility;
|
||||
private readonly IconsSaver _iconsSaver;
|
||||
|
||||
private bool AnyTargets => _data.Targets.Any(t => t);
|
||||
|
||||
public Texture2D CameraView { get; private set; }
|
||||
|
||||
|
||||
public IconsCreator()
|
||||
{
|
||||
_sceneHandler = new IconsCreatorInternalSceneHandler();
|
||||
_cameraUtility = new IconsCreatorCameraUtility();
|
||||
_iconsSaver = new IconsSaver();
|
||||
}
|
||||
|
||||
|
||||
public void InitializeEnvironment()
|
||||
{
|
||||
AddIconsCreationCameraTag();
|
||||
_sceneHandler.TryCreateScene(_cameraUtility.IconsCreationCameraTag);
|
||||
}
|
||||
|
||||
|
||||
private void AddIconsCreationCameraTag()
|
||||
{
|
||||
if (!InternalEditorUtility.tags.Contains(_cameraUtility.IconsCreationCameraTag))
|
||||
{
|
||||
InternalEditorUtility.AddTag(_cameraUtility.IconsCreationCameraTag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetData(IconsCreatorData data)
|
||||
{
|
||||
_data = data;
|
||||
|
||||
_cameraUtility.SetData(_data.Targets.FirstOrDefault(), _data.Size, _data.Padding);
|
||||
_iconsSaver.SetData(_data.Prefix, _data.Suffix);
|
||||
|
||||
OnDataChanged();
|
||||
}
|
||||
|
||||
|
||||
private void OnDataChanged()
|
||||
{
|
||||
if (!AnyTargets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateCameraView();
|
||||
}
|
||||
|
||||
|
||||
private void UpdateCameraView()
|
||||
{
|
||||
if (!AnyTargets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_sceneHandler.InteractWithTarget(_data.Targets[0], _data.RenderShadows, AdjustCamera);
|
||||
}
|
||||
|
||||
|
||||
private void AdjustCamera(GameObject target)
|
||||
{
|
||||
_cameraUtility.SetData(target, _data.Size, _data.Padding);
|
||||
_cameraUtility.RetrieveCamera();
|
||||
_cameraUtility.SetBackground(_data.BackgroundData);
|
||||
_cameraUtility.AdjustCamera();
|
||||
_cameraUtility.AdjustCamera();
|
||||
|
||||
CameraView = _cameraUtility.CaptureCameraView();
|
||||
}
|
||||
|
||||
|
||||
public void CreateIcon()
|
||||
{
|
||||
if (!_data.Targets.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (GameObject target in _data.Targets)
|
||||
{
|
||||
_sceneHandler.InteractWithTarget(target, _data.RenderShadows, t =>
|
||||
{
|
||||
AdjustCamera(t);
|
||||
|
||||
Texture2D icon = _cameraUtility.CaptureCameraView();
|
||||
_iconsSaver.SaveIcon(icon, target.name);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22da51def0be1bc459af9fc949bb0fd7
|
||||
timeCreated: 1673953622
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using IconsCreationTool.Editor.Utility.Extensions;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public class IconsCreatorCameraUtility
|
||||
{
|
||||
private const string ICONS_CREATION_CAMERA_TAG = "IconsCreationCamera";
|
||||
|
||||
private Camera _camera;
|
||||
private GameObject _targetObject;
|
||||
private Bounds _targetOrthographicBounds;
|
||||
|
||||
private int _size;
|
||||
private float _padding;
|
||||
|
||||
private IconBackgroundData _backgroundData;
|
||||
|
||||
private float _distanceToTarget = 10f;
|
||||
|
||||
private Vector3 CameraOffset => -_camera.transform.forward * _distanceToTarget;
|
||||
public string IconsCreationCameraTag => ICONS_CREATION_CAMERA_TAG;
|
||||
|
||||
|
||||
public void RetrieveCamera()
|
||||
{
|
||||
Scene activeScene = EditorSceneManager.GetActiveScene();
|
||||
|
||||
if (_camera)
|
||||
{
|
||||
bool isInValidScene = _camera.scene == activeScene;
|
||||
bool isTagged = _camera.gameObject.CompareTag(ICONS_CREATION_CAMERA_TAG);
|
||||
|
||||
if (isInValidScene && isTagged)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (GameObject rootGameObject in activeScene.GetRootGameObjects())
|
||||
{
|
||||
Camera camera = rootGameObject.GetComponentInChildren<Camera>();
|
||||
if (!camera)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (camera.CompareTag(ICONS_CREATION_CAMERA_TAG))
|
||||
{
|
||||
_camera = camera;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_camera)
|
||||
{
|
||||
Debug.LogWarning($"Something went wrong! No camera tagged \"{ICONS_CREATION_CAMERA_TAG}\" was found!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetData(GameObject targetObject, int size, float padding)
|
||||
{
|
||||
if (size < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(size));
|
||||
}
|
||||
|
||||
_targetObject = targetObject;
|
||||
_size = size;
|
||||
_padding = padding;
|
||||
}
|
||||
|
||||
|
||||
public void SetBackground(IconBackgroundData backgroundData)
|
||||
{
|
||||
_backgroundData = backgroundData;
|
||||
|
||||
switch (_backgroundData.Type)
|
||||
{
|
||||
case IconBackground.None:
|
||||
_camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
_camera.backgroundColor = Color.clear;
|
||||
break;
|
||||
|
||||
case IconBackground.Color:
|
||||
_camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
_camera.backgroundColor = _backgroundData.Color;
|
||||
break;
|
||||
|
||||
case IconBackground.Texture:
|
||||
_camera.clearFlags = CameraClearFlags.Nothing;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AdjustCamera()
|
||||
{
|
||||
if (!_targetObject)
|
||||
{
|
||||
Debug.LogWarning("No target object found!");
|
||||
return;
|
||||
}
|
||||
|
||||
_targetOrthographicBounds = _targetObject.GetOrthographicBounds(_camera);
|
||||
|
||||
SetRotation();
|
||||
SetPosition();
|
||||
SetOrthographicSize();
|
||||
}
|
||||
|
||||
|
||||
private void SetRotation()
|
||||
{
|
||||
_camera.transform.rotation = Quaternion.Euler(45f, -45f, 0f);
|
||||
}
|
||||
|
||||
|
||||
private void SetPosition()
|
||||
{
|
||||
_distanceToTarget = _targetOrthographicBounds.size.z / 2 + 10;
|
||||
Vector3 targetCenter = _targetOrthographicBounds.center;
|
||||
_camera.transform.position = targetCenter + CameraOffset;
|
||||
}
|
||||
|
||||
|
||||
private void SetOrthographicSize()
|
||||
{
|
||||
Vector2 minVertexPositionOnCameraPlane = _camera.transform.InverseTransformPoint(_targetOrthographicBounds.min);
|
||||
Vector2 maxVertexPositionOnCameraPlane = _camera.transform.InverseTransformPoint(_targetOrthographicBounds.max);
|
||||
Vector2 distance = maxVertexPositionOnCameraPlane - minVertexPositionOnCameraPlane;
|
||||
|
||||
_camera.orthographicSize = distance.Abs().BiggestComponentValue() * 0.5f / (1 - _padding);
|
||||
}
|
||||
|
||||
|
||||
public Texture2D CaptureCameraView()
|
||||
{
|
||||
if (_size < 1)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(_size));
|
||||
}
|
||||
|
||||
RenderTexture temporaryRenderTexture = RenderTexture.GetTemporary(_size, _size);
|
||||
|
||||
if (_backgroundData.Type == IconBackground.Texture)
|
||||
{
|
||||
Texture2D backgroundTexture = _backgroundData.Texture;
|
||||
if (backgroundTexture)
|
||||
{
|
||||
Graphics.Blit(backgroundTexture, temporaryRenderTexture);
|
||||
}
|
||||
}
|
||||
|
||||
_camera.targetTexture = temporaryRenderTexture;
|
||||
RenderTexture.active = _camera.targetTexture;
|
||||
|
||||
_camera.Render();
|
||||
|
||||
Texture2D image = new Texture2D(_size, _size);
|
||||
image.ReadPixels(new Rect(0, 0, _size, _size), 0, 0);
|
||||
image.Apply();
|
||||
|
||||
_camera.targetTexture = null;
|
||||
RenderTexture.active = null;
|
||||
|
||||
RenderTexture.ReleaseTemporary(temporaryRenderTexture);
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b7d46415ff10c84b95a9a23f90c3538
|
||||
timeCreated: 1673396133
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using IconsCreationTool.Editor.Utility.Extensions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public struct IconsCreatorData
|
||||
{
|
||||
public int Size { get; }
|
||||
public float Padding { get; }
|
||||
public string Prefix { get; }
|
||||
public string Suffix { get; }
|
||||
public IconBackgroundData BackgroundData { get; }
|
||||
public GameObject[] Targets { get; }
|
||||
public bool RenderShadows { get; }
|
||||
|
||||
|
||||
public IconsCreatorData(int size, float padding, string prefix, string suffix,
|
||||
IconBackgroundData backgroundData, List<Object> targets, bool renderShadows)
|
||||
{
|
||||
Size = size;
|
||||
Padding = padding;
|
||||
Prefix = prefix;
|
||||
Suffix = suffix;
|
||||
BackgroundData = backgroundData;
|
||||
Targets = targets.ExtractAllGameObjects().Where(g => g.HasVisibleMesh()).ToArray();
|
||||
RenderShadows = renderShadows;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91543813124f2ee4c8fdbb86fb49759c
|
||||
timeCreated: 1673953350
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using IconsCreationTool.Editor.Utility.Helpers;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public class IconsCreatorInternalSceneHandler
|
||||
{
|
||||
private const string ICONS_CREATOR_TARGETS_LAYER_NAME = "IconsCreatorTargets";
|
||||
private const string SCENE_NAME = "Icons_Creation";
|
||||
private readonly string _relativeScenePath = $"Assets/Plugins/IconsCreator/Scenes/{SCENE_NAME}.unity";
|
||||
|
||||
private Scene _prevActiveScene;
|
||||
|
||||
private string _iconsCreationCameraTag;
|
||||
|
||||
|
||||
public void TryCreateScene(string iconsCreationCameraTag)
|
||||
{
|
||||
string path = Path.GetFullPath(_relativeScenePath);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_iconsCreationCameraTag = iconsCreationCameraTag;
|
||||
|
||||
CreateScene();
|
||||
}
|
||||
|
||||
|
||||
private void CreateScene()
|
||||
{
|
||||
Scene prevActiveScene = EditorSceneManager.GetActiveScene();
|
||||
Scene scene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Additive);
|
||||
scene.name = SCENE_NAME;
|
||||
ulong targetLayer = (ulong) LayerMask.GetMask(ICONS_CREATOR_TARGETS_LAYER_NAME);
|
||||
EditorSceneManager.SetSceneCullingMask(scene, targetLayer);
|
||||
|
||||
SetupSceneComponents(scene);
|
||||
|
||||
SetupSceneRendering();
|
||||
|
||||
EditorSceneManager.SaveScene(scene, _relativeScenePath);
|
||||
|
||||
EditorSceneManager.CloseScene(scene, true);
|
||||
EditorSceneManager.SetActiveScene(prevActiveScene);
|
||||
}
|
||||
|
||||
|
||||
private void SetupSceneComponents(Scene scene)
|
||||
{
|
||||
Camera camera = null;
|
||||
Light light = null;
|
||||
|
||||
foreach (GameObject rootGameObject in scene.GetRootGameObjects())
|
||||
{
|
||||
camera ??= rootGameObject.GetComponentInChildren<Camera>();
|
||||
if (camera)
|
||||
{
|
||||
camera.gameObject.tag = _iconsCreationCameraTag;
|
||||
camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
camera.backgroundColor = Color.clear;
|
||||
camera.orthographic = true;
|
||||
}
|
||||
|
||||
light ??= rootGameObject.GetComponentInChildren<Light>();
|
||||
if (light)
|
||||
{
|
||||
light.useColorTemperature = false;
|
||||
light.color = Color.white;
|
||||
}
|
||||
|
||||
if (camera && light)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SetupSceneRendering()
|
||||
{
|
||||
RenderSettings.skybox = null;
|
||||
RenderSettings.ambientMode = AmbientMode.Flat;
|
||||
RenderSettings.ambientSkyColor = new Color(0.73f, 0.73f, 0.73f);
|
||||
}
|
||||
|
||||
|
||||
public void InteractWithTarget(GameObject targetObject, bool renderShadows, Action<GameObject> action)
|
||||
{
|
||||
Scene scene = default;
|
||||
|
||||
try
|
||||
{
|
||||
LayersHelper.CreateLayer(ICONS_CREATOR_TARGETS_LAYER_NAME);
|
||||
scene = OpenScene();
|
||||
|
||||
GameObject target = PlaceTarget(targetObject);
|
||||
|
||||
int layer = LayerMask.NameToLayer(ICONS_CREATOR_TARGETS_LAYER_NAME);
|
||||
target.layer = layer;
|
||||
foreach (Transform transform in target.GetComponentsInChildren<Transform>())
|
||||
{
|
||||
if (transform.TryGetComponent(out MeshRenderer renderer))
|
||||
{
|
||||
renderer.shadowCastingMode = renderShadows ?
|
||||
ShadowCastingMode.On : ShadowCastingMode.Off;
|
||||
}
|
||||
transform.gameObject.layer = layer;
|
||||
}
|
||||
|
||||
int cullingMask = LayerMask.GetMask(ICONS_CREATOR_TARGETS_LAYER_NAME);
|
||||
GameObject[] sceneRootGameObjects = scene.GetRootGameObjects();
|
||||
foreach (GameObject rootGameObject in sceneRootGameObjects)
|
||||
{
|
||||
Light light = rootGameObject.GetComponentInChildren<Light>();
|
||||
if (light)
|
||||
{
|
||||
light.cullingMask = cullingMask;
|
||||
}
|
||||
|
||||
Camera camera = rootGameObject.GetComponentInChildren<Camera>();
|
||||
if (camera)
|
||||
{
|
||||
camera.cullingMask = cullingMask;
|
||||
}
|
||||
}
|
||||
|
||||
action?.Invoke(target);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseScene(scene);
|
||||
LayersHelper.RemoveLayer(ICONS_CREATOR_TARGETS_LAYER_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Scene OpenScene()
|
||||
{
|
||||
_prevActiveScene = EditorSceneManager.GetActiveScene();
|
||||
Light[] allLightSources = Object.FindObjectsOfType<Light>();
|
||||
|
||||
foreach (Light lightSource in allLightSources)
|
||||
{
|
||||
lightSource.cullingMask &= ~LayerMask.GetMask(ICONS_CREATOR_TARGETS_LAYER_NAME);
|
||||
}
|
||||
|
||||
var openedScene = EditorSceneManager.OpenScene(_relativeScenePath, OpenSceneMode.Additive);
|
||||
EditorSceneManager.SetActiveScene(openedScene);
|
||||
|
||||
return openedScene;
|
||||
}
|
||||
|
||||
|
||||
private GameObject PlaceTarget(GameObject targetObject)
|
||||
{
|
||||
if (EditorSceneManager.GetActiveScene().name != SCENE_NAME)
|
||||
{
|
||||
Debug.LogWarning("Something went wrong! Target object can only be placed in the internal scene!");
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject target = Object.Instantiate(targetObject);
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
private void CloseScene(Scene scene)
|
||||
{
|
||||
EditorSceneManager.SetActiveScene(_prevActiveScene);
|
||||
|
||||
if (scene.IsValid())
|
||||
{
|
||||
EditorSceneManager.CloseScene(scene, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34a36f805fd2cd840af9e3aa27ca11fd
|
||||
timeCreated: 1673849804
|
||||
@@ -0,0 +1,431 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using IconsCreationTool.Editor.Utility.Extensions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public class IconsCreatorWindow : EditorWindow
|
||||
{
|
||||
[SerializeField] private IconBackground backgroundType;
|
||||
[SerializeField] private Color backgroundColor = Color.white;
|
||||
[SerializeField] private Texture2D backgroundTexture;
|
||||
|
||||
[SerializeField] private string prefix;
|
||||
[SerializeField] private string suffix = "_Icon";
|
||||
[SerializeField] private int size = 512;
|
||||
[SerializeField] private float padding;
|
||||
|
||||
[SerializeField] private bool renderShadows;
|
||||
|
||||
[SerializeField] private List<Object> targets = new List<Object>();
|
||||
|
||||
private const int PREVIEW_SIZE = 256;
|
||||
|
||||
private readonly IconsCreator _iconsCreator = new IconsCreator();
|
||||
|
||||
private Vector2 _scrollPosition;
|
||||
|
||||
private Texture2D _previewTexture;
|
||||
|
||||
private bool AnyTargets => targets.ExtractAllGameObjects().Where(g => g.HasVisibleMesh()).ToList().Any();
|
||||
|
||||
#region --- Window name ---
|
||||
|
||||
private const string MENU_NAME = "Tools/Icons Creator";
|
||||
private const string HOTKEYS = "%#I";
|
||||
private const string FULL_MENU_NAME = MENU_NAME + " " + HOTKEYS;
|
||||
|
||||
private const string TITLE = "Icons Creator";
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Serialized properties ---
|
||||
|
||||
private SerializedObject _serializedObject;
|
||||
|
||||
private SerializedProperty _backgroundTypeSerializedProperty;
|
||||
private SerializedProperty _backgroundColorSerializedProperty;
|
||||
private SerializedProperty _backgroundTextureSerializedProperty;
|
||||
private SerializedProperty _prefixSerializedProperty;
|
||||
private SerializedProperty _suffixSerializedProperty;
|
||||
private SerializedProperty _sizeSerializedProperty;
|
||||
private SerializedProperty _paddingSerializedProperty;
|
||||
private SerializedProperty _targetsObjectSerializedProperty;
|
||||
private SerializedProperty _renderShadowsSerializedProperty;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
[MenuItem(FULL_MENU_NAME)]
|
||||
private static void OpenWindow()
|
||||
{
|
||||
GetWindow<IconsCreatorWindow>(TITLE);
|
||||
}
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_iconsCreator.InitializeEnvironment();
|
||||
}
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Load();
|
||||
|
||||
SetupSerializedProperties();
|
||||
}
|
||||
|
||||
|
||||
private void Load()
|
||||
{
|
||||
prefix = EditorPrefs.GetString(nameof(prefix));
|
||||
suffix = EditorPrefs.GetString(nameof(suffix));
|
||||
size = EditorPrefs.GetInt(nameof(size));
|
||||
padding = EditorPrefs.GetFloat(nameof(padding));
|
||||
}
|
||||
|
||||
|
||||
private void SetupSerializedProperties()
|
||||
{
|
||||
_serializedObject = new SerializedObject(this);
|
||||
|
||||
_backgroundTypeSerializedProperty = _serializedObject.FindProperty(nameof(backgroundType));
|
||||
_backgroundColorSerializedProperty = _serializedObject.FindProperty(nameof(backgroundColor));
|
||||
_backgroundTextureSerializedProperty = _serializedObject.FindProperty(nameof(backgroundTexture));
|
||||
_prefixSerializedProperty = _serializedObject.FindProperty(nameof(prefix));
|
||||
_suffixSerializedProperty = _serializedObject.FindProperty(nameof(suffix));
|
||||
_sizeSerializedProperty = _serializedObject.FindProperty(nameof(size));
|
||||
_paddingSerializedProperty = _serializedObject.FindProperty(nameof(padding));
|
||||
_targetsObjectSerializedProperty = _serializedObject.FindProperty(nameof(targets));
|
||||
_renderShadowsSerializedProperty = _serializedObject.FindProperty(nameof(renderShadows));
|
||||
}
|
||||
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
|
||||
private void Save()
|
||||
{
|
||||
EditorPrefs.SetString(nameof(prefix), prefix);
|
||||
EditorPrefs.SetString(nameof(suffix), suffix);
|
||||
EditorPrefs.SetInt(nameof(size), size);
|
||||
EditorPrefs.SetFloat(nameof(padding), padding);
|
||||
}
|
||||
|
||||
|
||||
protected void OnGUI()
|
||||
{
|
||||
using GUILayout.ScrollViewScope scrollView = new GUILayout.ScrollViewScope(_scrollPosition);
|
||||
_scrollPosition = scrollView.scrollPosition;
|
||||
|
||||
_serializedObject.Update();
|
||||
|
||||
DrawSettings();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
|
||||
DrawObjectsOptions();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
|
||||
if (_serializedObject.ApplyModifiedProperties())
|
||||
{
|
||||
UpdateIconsCreator();
|
||||
}
|
||||
|
||||
DrawPreview();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
|
||||
DrawCreateIconButton();
|
||||
}
|
||||
|
||||
|
||||
private void DrawSettings()
|
||||
{
|
||||
using (IconsCreatorWindowElements.VerticalScopeBox)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Settings");
|
||||
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
|
||||
DrawBackgroundOptions();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
|
||||
DrawNamingOptions();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
|
||||
DrawSizingOptions();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
|
||||
DrawOtherOptions();
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawBackgroundOptions()
|
||||
{
|
||||
using (IconsCreatorWindowElements.VerticalScope)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Background");
|
||||
|
||||
DrawBackgroundTypeOption();
|
||||
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
|
||||
DrawBackgroundPickerOption();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawBackgroundTypeOption()
|
||||
{
|
||||
using (IconsCreatorWindowElements.HorizontalScope)
|
||||
{
|
||||
GUILayout.Label("Type", GUILayout.Width(EditorGUIUtility.labelWidth));
|
||||
|
||||
Undo.RecordObject(this, TITLE);
|
||||
backgroundType =
|
||||
(IconBackground) GUILayout.Toolbar((int) backgroundType, Enum.GetNames(typeof(IconBackground)));
|
||||
_backgroundTypeSerializedProperty.enumValueIndex = (int) backgroundType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawBackgroundPickerOption()
|
||||
{
|
||||
switch (backgroundType)
|
||||
{
|
||||
case IconBackground.None:
|
||||
break;
|
||||
|
||||
case IconBackground.Color:
|
||||
EditorGUILayout.PropertyField(_backgroundColorSerializedProperty);
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
break;
|
||||
|
||||
case IconBackground.Texture:
|
||||
EditorGUILayout.PropertyField(_backgroundTextureSerializedProperty);
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawNamingOptions()
|
||||
{
|
||||
using (IconsCreatorWindowElements.VerticalScope)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Naming");
|
||||
|
||||
EditorGUILayout.PropertyField(_prefixSerializedProperty);
|
||||
EditorGUILayout.PropertyField(_suffixSerializedProperty);
|
||||
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawSizingOptions()
|
||||
{
|
||||
using (IconsCreatorWindowElements.VerticalScope)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Sizing");
|
||||
|
||||
EditorGUILayout.IntSlider(_sizeSerializedProperty, 1, 1024);
|
||||
EditorGUILayout.Slider(_paddingSerializedProperty, 0f, 0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawOtherOptions()
|
||||
{
|
||||
using (IconsCreatorWindowElements.VerticalScope)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Other");
|
||||
|
||||
EditorGUILayout.PropertyField(_renderShadowsSerializedProperty);
|
||||
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawObjectsOptions()
|
||||
{
|
||||
using (IconsCreatorWindowElements.VerticalScopeBox)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Objects");
|
||||
|
||||
GUIContent content = new GUIContent("List");
|
||||
EditorGUILayout.PropertyField(_targetsObjectSerializedProperty, content);
|
||||
|
||||
int targetsCount = _targetsObjectSerializedProperty.arraySize;
|
||||
for (int i = 0; i < targetsCount; i++)
|
||||
{
|
||||
SerializedProperty targetProperty = _targetsObjectSerializedProperty.GetArrayElementAtIndex(i);
|
||||
ValidateTargetProperty(targetProperty);
|
||||
}
|
||||
|
||||
if (targets.Any(t => !t) || targets.Distinct().Count() < targets.Count)
|
||||
{
|
||||
if (GUILayout.Button("Remove invalid objects"))
|
||||
{
|
||||
RemoveInvalidTargetReferences();
|
||||
}
|
||||
}
|
||||
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ValidateTargetProperty(SerializedProperty targetProperty)
|
||||
{
|
||||
Object target = targetProperty.objectReferenceValue;
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isAllowedType = target is GameObject || target.IsFolderContainingGameObjects();
|
||||
if (!isAllowedType)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"Asset \"{target.name}\" is invalid! Asset has to be either a game object or a folder containing game objects!");
|
||||
targetProperty.objectReferenceValue = null;
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject targetObject = target as GameObject;
|
||||
if (targetObject)
|
||||
{
|
||||
string objectName = targetObject.name;
|
||||
|
||||
bool objectHasRenderingComponents = targetObject.GetComponentInChildren<MeshRenderer>() &&
|
||||
targetObject.GetComponentInChildren<MeshFilter>();
|
||||
if (!objectHasRenderingComponents)
|
||||
{
|
||||
Debug.LogWarning($"Game object \"{objectName}\" must have active MeshFilter and MeshRenderer components in its hierarchy!");
|
||||
targetProperty.objectReferenceValue = null;
|
||||
return;
|
||||
}
|
||||
|
||||
bool objectHasAtLeastOneMesh = targetObject.GetComponentsInChildren<MeshFilter>().Any(f => f.sharedMesh);
|
||||
if (!objectHasAtLeastOneMesh)
|
||||
{
|
||||
Debug.LogWarning($"Game object \"{objectName}\" must have at least one MeshFilter with an assigned mesh in its hierarchy!");
|
||||
targetProperty.objectReferenceValue = null;
|
||||
return;
|
||||
}
|
||||
|
||||
bool isSceneObject = targetObject.scene.IsValid();
|
||||
if (isSceneObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool isInAssetsFolder = AssetDatabase.GetAssetPath(target)[..6] == "Assets";
|
||||
if (!isInAssetsFolder)
|
||||
{
|
||||
Debug.LogWarning("Select scene object or an asset from Assets folder!");
|
||||
targetProperty.objectReferenceValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RemoveInvalidTargetReferences()
|
||||
{
|
||||
targets?.RemoveAll(t => !t);
|
||||
targets = targets?.Distinct().ToList();
|
||||
}
|
||||
|
||||
|
||||
private void DrawCreateIconButton()
|
||||
{
|
||||
if (!AnyTargets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (new EditorGUI.DisabledScope(!AnyTargets))
|
||||
{
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
|
||||
string buttonText = targets.ExtractAllGameObjects().Where(g => g.HasVisibleMesh()).ToList().Count > 1 ?
|
||||
"Create Icons" : "Create Icon";
|
||||
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button)
|
||||
{fixedHeight = 28, fontSize = 13, fontStyle = FontStyle.Bold};
|
||||
if (GUILayout.Button(buttonText, buttonStyle))
|
||||
{
|
||||
RemoveInvalidTargetReferences();
|
||||
UpdateIconsCreator();
|
||||
_iconsCreator.CreateIcon();
|
||||
}
|
||||
|
||||
IconsCreatorWindowElements.DrawRegularSpace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UpdateIconsCreator()
|
||||
{
|
||||
IconBackgroundData backgroundData = new IconBackgroundData(backgroundType, backgroundColor, backgroundTexture);
|
||||
IconsCreatorData data =
|
||||
new IconsCreatorData(size, padding, prefix, suffix, backgroundData, targets, renderShadows);
|
||||
_iconsCreator.SetData(data);
|
||||
|
||||
UpdatePreviewTexture();
|
||||
}
|
||||
|
||||
|
||||
private void UpdatePreviewTexture()
|
||||
{
|
||||
if (!AnyTargets)
|
||||
{
|
||||
_previewTexture = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Texture2D cameraView = _iconsCreator.CameraView;
|
||||
_previewTexture = cameraView.Resize(PREVIEW_SIZE);
|
||||
}
|
||||
|
||||
|
||||
private void DrawPreview()
|
||||
{
|
||||
if (!_previewTexture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (IconsCreatorWindowElements.VerticalScopeBox)
|
||||
{
|
||||
IconsCreatorWindowElements.DrawBoldLabel("Preview");
|
||||
|
||||
IconsCreatorWindowElements.DrawSmallSpace();
|
||||
|
||||
GUIStyle boxStyle = new GUIStyle(GUI.skin.box) {margin = new RectOffset(32, 32, 32, 32)};
|
||||
GUILayoutOption[] boxOptions = {GUILayout.Width(PREVIEW_SIZE), GUILayout.Height(PREVIEW_SIZE)};
|
||||
GUILayout.Box(_previewTexture, boxStyle, boxOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91277fc3577f1ad478ee8e146eec6404
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public static class IconsCreatorWindowElements
|
||||
{
|
||||
private const float REGULAR_SPACE_SIZE_PX = 4f;
|
||||
private const float SMALL_SPACE_SIZE_PX = 4f;
|
||||
|
||||
private static readonly GUIStyle BoldLabelStyle = new GUIStyle(EditorStyles.boldLabel);
|
||||
private static readonly GUIStyle ScopeBoxStyle = new GUIStyle(EditorStyles.helpBox);
|
||||
|
||||
public static GUILayout.HorizontalScope HorizontalScope => new GUILayout.HorizontalScope();
|
||||
public static GUILayout.VerticalScope VerticalScope => new GUILayout.VerticalScope();
|
||||
public static GUILayout.VerticalScope VerticalScopeBox => new GUILayout.VerticalScope(ScopeBoxStyle);
|
||||
|
||||
|
||||
public static void DrawSmallSpace()
|
||||
{
|
||||
GUILayout.Space(SMALL_SPACE_SIZE_PX);
|
||||
}
|
||||
|
||||
|
||||
public static void DrawRegularSpace()
|
||||
{
|
||||
GUILayout.Space(REGULAR_SPACE_SIZE_PX);
|
||||
}
|
||||
|
||||
|
||||
public static void DrawBoldLabel(string labelText)
|
||||
{
|
||||
GUILayout.Label(labelText, BoldLabelStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 120dcb142f643ce42ab3fcc7fe0f8806
|
||||
timeCreated: 1674396749
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Core
|
||||
{
|
||||
public class IconsSaver
|
||||
{
|
||||
private const string DIRECTORY = "/Textures/Icons/";
|
||||
|
||||
private string _prefix;
|
||||
private string _suffix;
|
||||
|
||||
|
||||
public void SetData(string prefix, string suffix)
|
||||
{
|
||||
_prefix = prefix;
|
||||
_suffix = suffix;
|
||||
}
|
||||
|
||||
|
||||
public void SaveIcon(Texture2D image, string name)
|
||||
{
|
||||
byte[] bytes = image.EncodeToPNG();
|
||||
Object.DestroyImmediate(image);
|
||||
|
||||
string path = Application.dataPath + DIRECTORY + _prefix + name + _suffix + ".png";
|
||||
if (!Directory.Exists(Application.dataPath + DIRECTORY))
|
||||
{
|
||||
Directory.CreateDirectory(Application.dataPath + DIRECTORY);
|
||||
}
|
||||
|
||||
File.WriteAllBytes(path, bytes);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
ConvertToSprite(path);
|
||||
}
|
||||
|
||||
|
||||
private void ConvertToSprite(string path)
|
||||
{
|
||||
string relativePath = path.Remove(0, Application.dataPath.Length - "Assets".Length);
|
||||
|
||||
TextureImporter textureImporter = (TextureImporter) AssetImporter.GetAtPath(relativePath);
|
||||
textureImporter.textureType = TextureImporterType.Sprite;
|
||||
textureImporter.mipmapEnabled = false;
|
||||
|
||||
textureImporter.SaveAndReimport();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
EditorGUIUtility.PingObject(textureImporter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 122eb1ce5c3704e4e8aa76298f26dfd6
|
||||
timeCreated: 1673397215
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35fa9bc7915b4094ab6b9d28a683fe2b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f0a7572d89767a40bf04793e3278fc5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Utility.Extensions
|
||||
{
|
||||
public static class GameObjectExtensions
|
||||
{
|
||||
public static Bounds GetOrthographicBounds(this GameObject gameObject, Camera camera)
|
||||
{
|
||||
Vector3 minScreenPosition = Vector3.positiveInfinity;
|
||||
Vector3 maxScreenPosition = Vector3.negativeInfinity;
|
||||
|
||||
MeshFilter[] meshFilters = gameObject.GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
if (!meshFilter.sharedMesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3[] vertices = meshFilter.sharedMesh.vertices;
|
||||
|
||||
foreach (Vector3 vertex in vertices)
|
||||
{
|
||||
Vector3 wsVertexPosition = meshFilter.transform.TransformPoint(vertex);
|
||||
Vector3 screenPosition = camera.WorldToScreenPoint(wsVertexPosition);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
minScreenPosition[i] = Mathf.Min(minScreenPosition[i], screenPosition[i]);
|
||||
maxScreenPosition[i] = Mathf.Max(maxScreenPosition[i], screenPosition[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 min = camera.ScreenToWorldPoint(minScreenPosition);
|
||||
Vector3 max = camera.ScreenToWorldPoint(maxScreenPosition);
|
||||
|
||||
Bounds bounds = new Bounds();
|
||||
bounds.SetMinMax(min, max);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
public static bool HasVisibleMesh(this GameObject gameObject)
|
||||
{
|
||||
bool hasVisibleMesh = false;
|
||||
MeshFilter[] meshFilters = gameObject.GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
if (!meshFilter)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool hasMesh = meshFilter.sharedMesh;
|
||||
if (!hasMesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool hasRendererForMesh = meshFilter.GetComponent<MeshRenderer>();
|
||||
if (!hasRendererForMesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasVisibleMesh = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return hasVisibleMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a93b83f00a629740be4e5a9ed5b25e2
|
||||
timeCreated: 1672935331
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Utility.Extensions
|
||||
{
|
||||
public static class TextureExtensions
|
||||
{
|
||||
public static Texture2D Resize(this Texture2D texture, int targetSize)
|
||||
{
|
||||
FilterMode filterMode = texture.filterMode;
|
||||
|
||||
RenderTexture temporaryRenderTexture = RenderTexture.GetTemporary(targetSize, targetSize);
|
||||
RenderTexture.active = temporaryRenderTexture;
|
||||
|
||||
Graphics.Blit(texture, temporaryRenderTexture);
|
||||
|
||||
Texture2D resizedTexture = new Texture2D(targetSize, targetSize);
|
||||
resizedTexture.filterMode = filterMode;
|
||||
|
||||
resizedTexture.ReadPixels(new Rect(0, 0, targetSize, targetSize), 0, 0);
|
||||
resizedTexture.Apply();
|
||||
|
||||
RenderTexture.ReleaseTemporary(temporaryRenderTexture);
|
||||
|
||||
return resizedTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d26dc795b5b53ed4ebb17b83dd396c37
|
||||
timeCreated: 1674288791
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Utility.Extensions
|
||||
{
|
||||
public static class UnityObjectExtensions
|
||||
{
|
||||
public static List<GameObject> ExtractAllGameObjects(this List<Object> objects)
|
||||
{
|
||||
List<GameObject> result = new List<GameObject>();
|
||||
GameObject[] gameObjects = objects.OfType<GameObject>().ToArray();
|
||||
result.AddRange(gameObjects);
|
||||
|
||||
Object[] folders = objects.Except(gameObjects).Where(o => o.IsFolder()).ToArray();
|
||||
foreach (Object folder in folders)
|
||||
{
|
||||
if (!folder)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string folderPath = AssetDatabase.GetAssetPath(folder)[7..];
|
||||
string[] filesPaths = Directory.GetFiles(Application.dataPath + "/" + folderPath, "*",
|
||||
SearchOption.AllDirectories);
|
||||
foreach (string filePath in filesPaths)
|
||||
{
|
||||
string relativeFilePath = filePath.Remove(0, Application.dataPath.Length - 6);
|
||||
GameObject gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(relativeFilePath);
|
||||
if (gameObject)
|
||||
{
|
||||
result.Add(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static bool IsFolder(this Object obj)
|
||||
{
|
||||
return AssetDatabase.IsValidFolder(AssetDatabase.GetAssetPath(obj));
|
||||
}
|
||||
|
||||
|
||||
public static bool IsFolderContainingGameObjects(this Object obj)
|
||||
{
|
||||
bool isFolder = obj.IsFolder();
|
||||
if (!isFolder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool containsGameObjects = false;
|
||||
|
||||
string folderPath = AssetDatabase.GetAssetPath(obj)[7..];
|
||||
string[] filesPaths = Directory.GetFiles(Application.dataPath + "/" + folderPath, "*",
|
||||
SearchOption.AllDirectories);
|
||||
foreach (string filePath in filesPaths)
|
||||
{
|
||||
string relativeFilePath = filePath.Remove(0, Application.dataPath.Length - 6);
|
||||
GameObject gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(relativeFilePath);
|
||||
if (!gameObject)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
containsGameObjects = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return containsGameObjects;
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e4ad67c4f556c54abd1c507d3735328
|
||||
timeCreated: 1674320433
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Utility.Extensions
|
||||
{
|
||||
public static class VectorExtensions
|
||||
{
|
||||
public static Vector2 Abs(this Vector2 a)
|
||||
{
|
||||
a.Set(Mathf.Abs(a.x), Mathf.Abs(a.y));
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
public static float BiggestComponentValue(this Vector2 a)
|
||||
{
|
||||
return Mathf.Max(a.x, a.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dab722235641d7f4c9e5bbf9514c2cdc
|
||||
timeCreated: 1672935401
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 55758c7903faa9e40b904ac1d00f4020
|
||||
timeCreated: 1674134791
|
||||
@@ -0,0 +1,106 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Editor.Utility.Helpers
|
||||
{
|
||||
internal static class LayersHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a layer at the next available index. Returns silently if layer already exists.
|
||||
/// </summary>
|
||||
/// <param name="newLayerName">Name of the layer to create</param>
|
||||
public static void CreateLayer(string newLayerName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(newLayerName))
|
||||
{
|
||||
throw new System.ArgumentNullException(nameof(newLayerName),
|
||||
"New layer name string is either null or empty.");
|
||||
}
|
||||
|
||||
const int builtInLayersCount = 5;
|
||||
|
||||
SerializedObject tagManager =
|
||||
new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty layersProperty = tagManager.FindProperty("layers");
|
||||
int layersCount = layersProperty.arraySize;
|
||||
|
||||
SerializedProperty firstEmptyLayerProperty = null;
|
||||
|
||||
for (int i = 0; i < layersCount; i++)
|
||||
{
|
||||
SerializedProperty layerProperty = layersProperty.GetArrayElementAtIndex(i);
|
||||
|
||||
string layerName = layerProperty.stringValue;
|
||||
|
||||
if (layerName == newLayerName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (i < builtInLayersCount || layerName != string.Empty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
firstEmptyLayerProperty ??= layerProperty;
|
||||
}
|
||||
|
||||
if (firstEmptyLayerProperty == null)
|
||||
{
|
||||
Debug.LogError("Maximum limit of " + layersCount + " layers exceeded. Layer \"" + newLayerName + "\" not created.");
|
||||
return;
|
||||
}
|
||||
|
||||
firstEmptyLayerProperty.stringValue = newLayerName;
|
||||
tagManager.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
|
||||
public static void RemoveLayer(string existingLayerName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(existingLayerName))
|
||||
{
|
||||
throw new System.ArgumentNullException(nameof(existingLayerName),
|
||||
"Layer name string is either null or empty.");
|
||||
}
|
||||
|
||||
const int builtInLayersCount = 5;
|
||||
|
||||
SerializedObject tagManager =
|
||||
new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty layersProperty = tagManager.FindProperty("layers");
|
||||
int layersCount = layersProperty.arraySize;
|
||||
|
||||
SerializedProperty existingLayerProperty = null;
|
||||
|
||||
for (int i = 0; i < layersCount; i++)
|
||||
{
|
||||
SerializedProperty layerProperty = layersProperty.GetArrayElementAtIndex(i);
|
||||
|
||||
string layerName = layerProperty.stringValue;
|
||||
|
||||
bool validLayer = i < builtInLayersCount || layerName != string.Empty;
|
||||
if (!validLayer)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layerName != existingLayerName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
existingLayerProperty ??= layerProperty;
|
||||
}
|
||||
|
||||
if (existingLayerProperty == null)
|
||||
{
|
||||
Debug.LogError($"Layer named \"{existingLayerName}\" was not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
existingLayerProperty.stringValue = string.Empty;
|
||||
tagManager.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 836ab8032815695489738920b838a6da
|
||||
timeCreated: 1674134797
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "xyperine.IconsCreator.Editor",
|
||||
"rootNamespace": "IconsCreationTool",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36ad009b5e1041b4b8da93f83cbd29cb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eafc22d035e73454fae5eef8eadb5faf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24886f9dae82b7742bba6cc0ca0e4743
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using IconsCreationTool.Editor.Core;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace IconsCreationTool.Tests.Editor
|
||||
{
|
||||
public class _0_IconAssetValidityTests
|
||||
{
|
||||
private const string DESIRED_NAME = "TestIcon";
|
||||
private const string DESIRED_PREFIX = "Test_";
|
||||
private const string DESIRED_SUFFIX = "_Icon";
|
||||
private const string FULL_NAME = DESIRED_PREFIX + DESIRED_NAME + DESIRED_SUFFIX;
|
||||
private const string FILE_EXTENSION = ".png";
|
||||
private const string PATH = "Assets/Textures/Icons/";
|
||||
|
||||
private readonly IconsCreator _iconsCreator = new IconsCreator();
|
||||
|
||||
private TextureImporter _textureImporter;
|
||||
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Initialize()
|
||||
{
|
||||
IconBackgroundData backgroundData = new IconBackgroundData(IconBackground.None, default, default);
|
||||
GameObject target = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
|
||||
target.name = DESIRED_NAME;
|
||||
target.transform.position = new Vector3(1024f, 0f, 1024f);
|
||||
List<Object> targets = new List<Object> {target};
|
||||
IconsCreatorData data =
|
||||
new IconsCreatorData(512, 0f, DESIRED_PREFIX, DESIRED_SUFFIX, backgroundData, targets, false);
|
||||
_iconsCreator.SetData(data);
|
||||
|
||||
_iconsCreator.CreateIcon();
|
||||
|
||||
_textureImporter =
|
||||
(TextureImporter) AssetImporter.GetAtPath(PATH + FULL_NAME + FILE_EXTENSION);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Exist_At_Given_Path()
|
||||
{
|
||||
Assert.IsNotNull(_textureImporter);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Have_Expected_Name()
|
||||
{
|
||||
string name = _textureImporter.assetPath.Remove(0, PATH.Length);
|
||||
name = name.Remove(name.Length - FILE_EXTENSION.Length);
|
||||
|
||||
Assert.AreEqual(DESIRED_PREFIX + DESIRED_NAME + DESIRED_SUFFIX, name);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_A_Sprite()
|
||||
{
|
||||
TextureImporterType textureType = _textureImporter.textureType;
|
||||
|
||||
Assert.AreEqual(TextureImporterType.Sprite, textureType);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 668250bf04ed0314f9ef995b0c8b048f
|
||||
timeCreated: 1674129648
|
||||
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IconsCreationTool.Editor.Core;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace IconsCreationTool.Tests.Editor
|
||||
{
|
||||
public class _1_IconSizeTests
|
||||
{
|
||||
private const string DESIRED_NAME = "TestIcon";
|
||||
private const string DESIRED_PREFIX = "Test_";
|
||||
private const string DESIRED_SUFFIX = "_Icon";
|
||||
private const string FULL_NAME = DESIRED_PREFIX + DESIRED_NAME + DESIRED_SUFFIX;
|
||||
private const string FILE_EXTENSION = ".png";
|
||||
private const string PATH = "Assets/Textures/Icons/";
|
||||
|
||||
private readonly IconsCreator _iconsCreator = new IconsCreator();
|
||||
|
||||
private List<Object> _targets;
|
||||
|
||||
private TextureImporter _textureImporter;
|
||||
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Initialize()
|
||||
{
|
||||
GameObject target = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
|
||||
target.name = DESIRED_NAME;
|
||||
target.transform.position = new Vector3(1024f, 0f, 1024f);
|
||||
_targets= new List<Object> {target};
|
||||
}
|
||||
|
||||
|
||||
private void SetSize(int size)
|
||||
{
|
||||
IconBackgroundData backgroundData = new IconBackgroundData(IconBackground.None, default, default);
|
||||
IconsCreatorData data =
|
||||
new IconsCreatorData(size, 0f, DESIRED_PREFIX, DESIRED_SUFFIX, backgroundData, _targets, false);
|
||||
_iconsCreator.SetData(data);
|
||||
}
|
||||
|
||||
|
||||
private void CreateIcon()
|
||||
{
|
||||
_iconsCreator.CreateIcon();
|
||||
|
||||
_textureImporter =
|
||||
(TextureImporter) AssetImporter.GetAtPath(PATH + FULL_NAME + FILE_EXTENSION);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_32px_Wide()
|
||||
{
|
||||
const int size = 32;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, width);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_512px_Wide()
|
||||
{
|
||||
const int size = 512;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, width);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_1024px_Wide()
|
||||
{
|
||||
const int size = 1024;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, width);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_381px_Wide()
|
||||
{
|
||||
const int size = 381;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, width);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_32px_High()
|
||||
{
|
||||
const int size = 1024;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, height);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_512px_High()
|
||||
{
|
||||
const int size = 512;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, height);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_1024px_High()
|
||||
{
|
||||
const int size = 1024;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, height);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Be_381px_High()
|
||||
{
|
||||
const int size = 1024;
|
||||
|
||||
SetSize(size);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
|
||||
Assert.AreEqual(size, height);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Asset_Should_Have_1to1_Aspect_Ratio()
|
||||
{
|
||||
SetSize(512);
|
||||
CreateIcon();
|
||||
|
||||
_textureImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
|
||||
float aspectRatio = (float) width / height;
|
||||
|
||||
Assert.AreEqual(1, aspectRatio);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Trying_To_Make_Icon_Of_Less_Than_1px_Should_Throw_ArgumentOutOfRangeException()
|
||||
{
|
||||
const int size = -1;
|
||||
|
||||
TestDelegate setCameraDataAction = () => SetSize(size);
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(setCameraDataAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fedef1e715069804ebe4325d945b0c8f
|
||||
timeCreated: 1674129648
|
||||
Generated
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "xyperine.IconsCreator.Editor.Tests",
|
||||
"rootNamespace": "IconsCreationTool.Tests",
|
||||
"references": [
|
||||
"UnityEngine.TestRunner",
|
||||
"UnityEditor.TestRunner",
|
||||
"xyperine.IconsCreator.Editor"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
Generated
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b279d1da230c2d4fab5b8a9e481321b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user