Skip to content

Instantly share code, notes, and snippets.

@timrach
Created December 18, 2020 10:13
Show Gist options
  • Save timrach/0a105428976681fd8bb372b5d340062d to your computer and use it in GitHub Desktop.
Save timrach/0a105428976681fd8bb372b5d340062d to your computer and use it in GitHub Desktop.
Unity editor window to bulk replace sprites of selected SpriteRenderer components
using System.Collections.Generic;
using UnityEditor;
using System;
using UnityEngine;
public class SpriteReplacerSettingsAsset
{
[MenuItem("Assets/Create/SpriteReplacerSettings")]
public static void CreateAsset()
{
SpriteReplacerSettings asset = ScriptableObject.CreateInstance<SpriteReplacerSettings>();
AssetDatabase.CreateAsset(asset, "Assets/SpriteReplacerSettings.asset");
AssetDatabase.SaveAssets();
EditorUtility.FocusProjectWindow();
Selection.activeObject = asset;
}
}
public class SpriteReplacer : EditorWindow
{
public SpriteReplacerSettings settings;
public bool compactView = false;
Vector2 scrollposition = Vector2.zero;
List<SpriteRenderer> targets = new List<SpriteRenderer>();
List<int> targetReplacement = new List<int>();
// Add menu named "My Window" to the Window menu
[MenuItem("Window/SpriteReplacer")]
static void Init()
{
// Get existing open window or if none, make a new one:
SpriteReplacer window = (SpriteReplacer)EditorWindow.GetWindow(typeof(SpriteReplacer));
window.minSize = new Vector2(200, 400);
window.Show();
}
void OnEnable()
{
if (EditorPrefs.HasKey("SpriteReplacer_Setting"))
{
string objectPath = EditorPrefs.GetString("SpriteReplacer_Setting");
settings = AssetDatabase.LoadAssetAtPath(objectPath, typeof(SpriteReplacerSettings)) as SpriteReplacerSettings;
}
}
private void OnDisable()
{
EditorUtility.SetDirty(settings);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
void OnGUI()
{
compactView = EditorGUILayout.Toggle("Compact View", compactView);
if (!settings)
{
RenderSetup();
return;
}
int columns = Mathf.FloorToInt(EditorGUIUtility.currentViewWidth / 150);
RenderSpritesList(columns:columns);
TargetSelection();
EditorGUILayout.LabelField($"Will apply change to {targets.Count} gameObjects", GUI.skin.GetStyle("HelpBox"));
ReplacementButton();
}
public string GetProjectName()
{
string[] s = Application.dataPath.Split('/');
string projectName = s[s.Length - 2];
Debug.Log("project = " + projectName);
return projectName;
}
private void RenderSetup()
{
settings = (SpriteReplacerSettings)EditorGUILayout.ObjectField("Settings asset", settings, typeof(SpriteReplacerSettings), false);
}
private Sprite SpriteField(string label, Sprite sprite)
{
if (compactView)
{
return (Sprite)EditorGUILayout.ObjectField(sprite, typeof(Sprite), true);
}else
{
return (Sprite)EditorGUILayout.ObjectField(label, sprite, typeof(Sprite), true);
}
}
private void RenderSpritesList(int columns = 1)
{
scrollposition = EditorGUILayout.BeginScrollView(scrollposition);
EditorGUILayout.BeginVertical();
if (settings.toReplace.Count == 0)
{
settings.toReplace.Add(null);
settings.replacement.Add(null);
}
if (GUILayout.Button("Add Replacement"))
{
settings.toReplace.Add(null);
settings.replacement.Add(null);
}
EditorGUILayout.BeginHorizontal();
int rowsPerColumn = settings.toReplace.Count / columns;
for (int column = 0; column < columns; column++)
{
EditorGUILayout.BeginVertical();
int rowsAlreadyPlaced = rowsPerColumn * column;
int rowsLeftToPlace = settings.toReplace.Count - rowsAlreadyPlaced;
int rowsInThisColumn = Math.Min(rowsLeftToPlace, rowsPerColumn);
for (int i = 0 + rowsAlreadyPlaced; i < rowsInThisColumn + rowsAlreadyPlaced; i++)
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("-", GUILayout.Width(18), GUILayout.Height(18)))
{
settings.toReplace.Remove(settings.toReplace[i]);
settings.replacement.Remove(settings.replacement[i]);
}
EditorGUIUtility.labelWidth = 1;
settings.toReplace[i] = SpriteField("", settings.toReplace[i]);
EditorGUIUtility.labelWidth = 1;
settings.replacement[i] = SpriteField("", settings.replacement[i]);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
if(column < columns - 1)
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.EndScrollView();
EditorGUIUtility.labelWidth = 0;
}
private void TargetSelection()
{
if (GUILayout.Button("Select Targets"))
{
List<GameObject> newSelection = new List<GameObject>();
targets.Clear();
targetReplacement.Clear();
SpriteRenderer[] spriteRenderers = FindObjectsOfType<SpriteRenderer>();
foreach (SpriteRenderer renderer in spriteRenderers)
{
for (int i = 0; i < settings.toReplace.Count; i++)
{
if (renderer.sprite.name == settings.toReplace[i].name)
{
newSelection.Add(renderer.gameObject);
targets.Add(renderer);
targetReplacement.Add(i);
}
}
}
Selection.objects = newSelection.ToArray();
}
}
private void ReplacementButton()
{
if (Selection.objects.Length > 0 && GUILayout.Button("Apply to selection!", GUILayout.Height(40)))
{
for (int i = 0; i < targets.Count; i++)
{
targets[i].sprite = settings.replacement[targetReplacement[i]];
}
}
}
}
using UnityEngine;
using System.Collections.Generic;
public class SpriteReplacerSettings : ScriptableObject
{
public List<Sprite> toReplace;
public List<Sprite> replacement;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment