ProjectDDD/Assets/_Datas/02.Scripts/AssetPostprocessor/AssetPostprocessorSprite.cs
2025-06-17 20:47:57 +09:00

290 lines
11 KiB (Stored with Git LFS)
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
using Superlazy;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;
namespace DDD
{
public static class AssetPostprocessorSprite
{
private static readonly HashSet<string> TargetPaths = new HashSet<string>();
public static void OnPreprocessTexture(TextureImporter importer)
{
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Single;
importer.GetSourceTextureWidthAndHeight(out var width, out var height);
importer.spritePixelsPerUnit = width <= height ? width : height;
importer.sRGBTexture = true;
importer.isReadable = false;
importer.mipmapEnabled = false;
importer.streamingMipmaps = false;
importer.wrapMode = TextureWrapMode.Clamp;
importer.filterMode = FilterMode.Bilinear;
importer.textureCompression = TextureImporterCompression.Uncompressed;
importer.crunchedCompression = false;
var textureSettings = new TextureImporterSettings();
importer.ReadTextureSettings(textureSettings);
textureSettings.spriteMeshType = SpriteMeshType.FullRect;
textureSettings.spriteExtrude = 2;
importer.SetTextureSettings(textureSettings);
}
public static void OnRemove(string path, string movePath)
{
var upperPath = path.ToUpper();
if (upperPath.Contains("ASSETS/_DATAS/RAW/SPRITES/") == false ||
upperPath.Contains(".PNG") == false) return;
if (TargetPaths.Contains(path) == false)
{
TargetPaths.Add(path);
}
}
public static void OnAdd(string path)
{
var upperPath = path.ToUpper();
if (upperPath.Contains("ASSETS/_DATAS/RAW/SPRITES/") == false ||
upperPath.Contains(".PNG") == false) return;
if (TargetPaths.Contains(path) == false)
{
TargetPaths.Add(path);
}
}
public static void CreateAtlas(string path, string destPath)
{
var oldAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(destPath);
if (oldAtlas != null)
{
AssetDatabase.DeleteAsset(destPath);
}
var di = new DirectoryInfo(path);
if (di.Exists == false) return;
var objects = new List<Object>();
foreach (var file in di.GetFiles())
{
if (file.Name.ToUpper().IsRight(".PNG") == false) continue;
var filePath = path + "/" + file.Name;
var fileName = file.Name.Substring(0, file.Name.Length - ".png".Length);
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(filePath);
var maxSize = sprite.rect.size.x > sprite.rect.size.y ? sprite.rect.size.x : sprite.rect.size.y;
if (maxSize > 1024)
{
CreateSingleAtlas(filePath, path.Replace("/Raw/", "/Addressables/") + $"_{fileName}.spriteatlasv2");
continue;
}
objects.Add(sprite);
}
if (objects.Count == 0) return;
Utils.MakeFolderFromFilePath(destPath);
var atlas = new SpriteAtlasAsset();
var spriteAtlasComponents = new List<IPostProcessorSpriteAtlas>();
spriteAtlasComponents.CreateInstanceList();
foreach (var component in spriteAtlasComponents)
{
component.OnAddSprite(atlas);
}
atlas.Add(objects.ToArray());
SpriteAtlasAsset.Save(atlas, destPath);
AssetDatabase.Refresh();
var sai = (SpriteAtlasImporter)AssetImporter.GetAtPath(destPath);
sai.packingSettings = new SpriteAtlasPackingSettings
{
enableRotation = false,
enableTightPacking = false,
enableAlphaDilation = false,
padding = 4,
blockOffset = 0
};
sai.textureSettings = new SpriteAtlasTextureSettings
{
filterMode = FilterMode.Bilinear,
sRGB = true,
generateMipMaps = false
};
}
public static void CreateSingleAtlas(string path, string destPath)
{
var oldAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(destPath);
if (oldAtlas != null)
{
AssetDatabase.DeleteAsset(destPath);
}
Utils.MakeFolderFromFilePath(destPath);
var atlas = new SpriteAtlasAsset();
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
atlas.Add(new Object[] { sprite });
var spriteAtlasComponents = new List<IPostProcessorSpriteAtlas>();
spriteAtlasComponents.CreateInstanceList();
foreach (var component in spriteAtlasComponents)
{
component.OnAddSprite(atlas);
}
SpriteAtlasAsset.Save(atlas, destPath);
AssetDatabase.Refresh();
var sai = (SpriteAtlasImporter)AssetImporter.GetAtPath(destPath);
sai.packingSettings = new SpriteAtlasPackingSettings
{
enableRotation = false,
enableTightPacking = false,
enableAlphaDilation = false,
padding = 4,
blockOffset = 0
};
sai.textureSettings = new SpriteAtlasTextureSettings
{
filterMode = FilterMode.Bilinear,
sRGB = true,
generateMipMaps = false
};
}
public static void CreatePrefab(string path, string destPath)
{
try
{
var spriteCreateComponents = new List<IPostProcessorSpriteAtlas>();
spriteCreateComponents.CreateInstanceList();
var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
if (sprite == null) return;
GameObject prefab = new GameObject(sprite.name);
prefab.transform.localPosition = Vector3.zero;
prefab.transform.localRotation = Quaternion.identity;
prefab.name = sprite.name;
GameObject visualLook = new GameObject("VisualLook");
visualLook.transform.SetParent(prefab.transform);
visualLook.transform.localPosition = Vector3.zero;
visualLook.transform.localRotation = Quaternion.Euler(new Vector3(40f, 0f, 0f));
SpriteRenderer spriteRenderer = visualLook.AddComponent<SpriteRenderer>();
spriteRenderer.sprite = sprite;
spriteRenderer.sortingOrder = 5;
// var guids = AssetDatabase.FindAssets("t:Material", new string[] { Utils.FolderPath(path) });
// var materials = guids
// .Select(guid => AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(guid)))
// .ToDictionary(m => m.name);
//
// foreach (var renderer in model.GetComponentsInChildren<Renderer>())
// {
// var sharedMaterials =
// new Material[renderer.sharedMaterials.Length]; // Material을 직접 엘리먼트로 대입하면 안되고 배열을 통으로 넣어야함
// for (var i = 0; i < renderer.sharedMaterials.Length; ++i)
// {
// if (materials.TryGetValue($"{renderer.name}_{i + 1}", out var numMat))
// {
// sharedMaterials[i] = numMat;
// }
// else if (materials.TryGetValue(renderer.name, out var mat))
// {
// sharedMaterials[i] = mat;
// }
// else if (materials.TryGetValue(go.name, out var defaultMat))
// {
// sharedMaterials[i] = defaultMat;
// }
// else
// {
// sharedMaterials[i] = renderer.sharedMaterials[i];
// // 에러인가? 잠깐 파일 안갖다놨을뿐인가?
// }
// }
//
// renderer.sharedMaterials = sharedMaterials;
// }
//
// var res = prefab.AddComponent<SLResourceObject>();
//res.Init();
Utils.MakeFolderFromFilePath(destPath);
// {
// // Make Duumy(for test)
// var dummyObj = Object.Instantiate(model);
// var anim = dummyObj.GetComponentInChildren<Animator>();
// var controller =
// AnimatorController.CreateAnimatorControllerAtPath(GetPrefabPath(path)
// .Replace(".prefab", ".controller"));
//
// anim.runtimeAnimatorController = controller;
// var rootStateMachine = controller.layers[0].stateMachine;
//
// var clipids = AssetDatabase.FindAssets("t:AnimationClip",
// new string[] { SLFileUtility.FolderPath(path) });
// foreach (var guid in clipids)
// {
// var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(AssetDatabase.GUIDToAssetPath(guid));
// if (clip != null)
// {
// var state = rootStateMachine.AddState(clip.name);
// state.motion = clip;
// }
// }
//
// var dummy = PrefabUtility.SaveAsPrefabAssetAndConnect(dummyObj, GetPrefabPath(path),
// InteractionMode.AutomatedAction);
//
// Object.DestroyImmediate(dummyObj, false);
// }
AssetDatabase.DeleteAsset(destPath);
var newPrefab =
PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, destPath, InteractionMode.AutomatedAction);
Object.DestroyImmediate(prefab, false);
Debug.Log("Build : " + destPath, newPrefab);
}
catch (System.Exception e)
{
Debug.LogError("Cant build " + destPath + "\n" + e);
}
}
public static void BuildTarget()
{
foreach (var path in TargetPaths)
{
CreateAtlas(Utils.FolderPath(path), Utils.FolderPath(path).Replace("/Raw/", "/Addressables/") + ".spriteatlasv2");
CreatePrefab(path, (path.Replace("/Raw/Sprites/", "/Addressables/") + ".prefab").Replace(".png", ""));
}
TargetPaths.Clear();
}
}
}