#if UNITY_EDITROR using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using NaughtyAttributes; using UnityEditor; #endif using UnityEngine; public class SplitByUV : MonoBehaviour { #if UNITY_EDITROR public Texture2D texture; public float colorThreshold = 0.1f; public Texture2D newTexture; public float cellSize = 1f / 8f; public int textureHeight = 64; public int textureWidth = 8; [Button("UVSave")] public void SaveTextureAsPNG() { byte[] textureBytes = newTexture.EncodeToPNG(); string path = Path.Combine(Application.dataPath, "fileName"); if (File.Exists(path)) { File.Delete(path); } File.WriteAllBytes(path, textureBytes); Debug.Log("Texture saved to: " + path); AssetDatabase.Refresh(); } [Button("UVGenerate")] public void CopyUVTexture() { MeshFilter meshRenderer = GetComponent(); if (meshRenderer == null || texture == null) { Debug.LogError("Missing SkinnedMeshRenderer or Texture2D!"); return; } Mesh mesh = meshRenderer.sharedMesh; Vector2[] uv = mesh.uv; Color[] textureColors = texture.GetPixels(); int width = texture.width; int height = texture.height; Dictionary> colorUVMap = new Dictionary>(); for (int i = 0; i < uv.Length; i++) { int x = Mathf.Clamp((int)(uv[i].x * width), 0, width - 1); int y = Mathf.Clamp((int)(uv[i].y * height), 0, height - 1); Color pixelColor = textureColors[y * width + x]; bool found = false; foreach (var key in colorUVMap.Keys) { if (Vector4.Distance(pixelColor, key) < colorThreshold) { colorUVMap[key].Add(uv[i]); found = true; break; } } if (!found) colorUVMap[pixelColor] = new List { uv[i] }; } List colorHeightMap = new List() { }; foreach (var kvp in colorUVMap) { Color color = kvp.Key; List uvPoints = kvp.Value; float minX = float.MaxValue, minY = float.MaxValue; float maxX = float.MinValue, maxY = float.MinValue; foreach (Vector2 uvCoord in uvPoints) { if (uvCoord.x < minX) minX = uvCoord.x; if (uvCoord.y < minY) minY = uvCoord.y; if (uvCoord.x > maxX) maxX = uvCoord.x; if (uvCoord.y > maxY) maxY = uvCoord.y; } int minPixelX = Mathf.RoundToInt(minX * width); int minPixelY = Mathf.RoundToInt(minY * height); int maxPixelX = Mathf.RoundToInt(maxX * width); int maxPixelY = Mathf.RoundToInt(maxY * height); int boundH = maxPixelY - minPixelY; int boundW = maxPixelX - minPixelX; colorHeightMap.Add(new int[] {minPixelX, minPixelY, maxPixelX, maxPixelY,boundH, boundW }); Debug.Log($"Index:{minPixelX}:{minPixelY}-{maxPixelX}:{maxPixelY}..{boundH}:{boundW}"); } var colors = colorUVMap.Keys.ToList(); var points = colorUVMap.Values.ToList(); int indexation = 0; int colorize = 0; RenderTexture rt = RenderTexture.GetTemporary(textureWidth*colors.Count, textureHeight, 0); RenderTexture.active = rt; Texture2D textureN = new Texture2D(textureWidth*colors.Count, textureHeight, TextureFormat.RGBA32, false); textureN.ReadPixels(new Rect(0, 0, textureWidth*colors.Count, textureHeight), 0, 0); textureN.Apply(); RenderTexture.active = null; RenderTexture.ReleaseTemporary(rt); newTexture = textureN; Dictionary forNewUV = new Dictionary(); foreach (var color in colors) { for (int x = 0 + colorize*textureWidth; x < textureWidth + colorize*textureWidth; x++) { for (int y = 0; y < textureHeight; y++) { newTexture.SetPixel(x,y,new Color(color.r, color.g, color.b, color.a)); if (!forNewUV.ContainsKey(color)) forNewUV.Add(color, new Vector2((float)x/width,(float)y/height )); } } colorize++; } foreach (var colorMap in colorHeightMap) { var pointForIndex = points[indexation]; foreach (var listOffer in pointForIndex) { var mz = Mathf.RoundToInt(listOffer.x * width) - colorMap[0]; var kz = Mathf.RoundToInt(listOffer.y * height) - colorMap[1]; var hn2 = 0; var hn1 = 0; if (colorMap[4] != 0) hn2 = Mathf.RoundToInt((kz / colorMap[4])*textureHeight); if (colorMap[5] != 0) hn1 = Mathf.RoundToInt((mz / colorMap[5])*textureWidth); var y = hn2 + indexation*textureHeight; var x = hn1 + indexation*textureWidth; Debug.Log($"{x}:{y}:{colors[indexation]}"); } indexation++; } newTexture.Apply(); //forNewUV.Values.ToArray(); var listNewUV = new List(); foreach (var bound in mesh.uv) { int x = Mathf.Clamp((int)(bound.x * width), 0, width - 1); int y = Mathf.Clamp((int)(bound.y * height), 0, height - 1); Color pixelColor = textureColors[y * width + x]; foreach (var key in forNewUV.Keys) { if (Vector4.Distance(pixelColor, key) < colorThreshold) {listNewUV.Add(forNewUV[key]); break;} } } Debug.Log($"{listNewUV.Count} , { mesh.uv.Length}"); mesh.uv = listNewUV.ToArray(); } #endif }