150 lines
5.8 KiB
C#
Raw Normal View History

2025-09-06 17:17:39 +04:00
#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<MeshFilter>();
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<Color, List<Vector2>> colorUVMap = new Dictionary<Color, List<Vector2>>();
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<Vector2> { uv[i] };
}
List<int[]> colorHeightMap = new List<int[]>() { };
foreach (var kvp in colorUVMap)
{
Color color = kvp.Key;
List<Vector2> 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<Color,Vector2> forNewUV = new Dictionary<Color,Vector2>();
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<Vector2>();
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
}