ProjectDDD/Packages/SLUnity/SLUI/SpriteText.cs
2025-06-25 11:33:17 +09:00

99 lines
3.4 KiB (Stored with Git LFS)
C#

using System.Linq;
using System.Text;
using Superlazy;
using UnityEngine;
public class SpriteText : SLTag
{
public override string Tag => "ST";
private Texture2D baseTex;
public override string GetValue(SLEntity value)
{
if (baseTex == null) InitTexture();
if (SLGame.Session["SpriteTexts"][value] == false)
{
var path = SLSystem.Data["ImageSprites"][value]["Path"];
if (path == false) return value;
var sprite = SLResources.GetSprite(path);
var spritePixels = Clone(sprite.texture, sprite.textureRect).GetPixels();
var targetPixels = Resize(spritePixels, Mathf.RoundToInt(sprite.rect.width), Mathf.RoundToInt(sprite.rect.height), 128, 128);
var idx = SLGame.Session["SpriteTexts"].Count();
SLGame.Session["SpriteTexts"][value]["Index"] = idx;
var baseX = idx % 16 * 128;
var baseY = (2048 - 128) - (idx / 16 * 128);
for (var x = 0; x < 128; ++x)
{
for (var y = 0; y < 128; ++y)
{
var color = targetPixels[y * 128 + x];
baseTex.SetPixel(x + baseX, y + baseY, color);
}
}
baseTex.Apply(false);
}
return $"<sprite={SLGame.Session["SpriteTexts"][value]["Index"]}>"; // "Sprite=0" 같은 형태
}
private void InitTexture()
{
baseTex = Resources.Load<Texture2D>("SpriteTextBase");
}
private Texture2D Clone(Texture2D source, Rect rect)
{
// 새 텍스처를 스프라이트 크기로 생성
var readableTexture = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGBA32, false);
// 원본 텍스처에서 스프라이트 영역의 픽셀을 읽어들임
var renderTex = RenderTexture.GetTemporary(source.width, source.height, 0);
Graphics.Blit(source, renderTex);
// 읽을 영역을 설정 (rect를 사용하여 원본에서 스프라이트 부분만 읽음)
RenderTexture.active = renderTex;
readableTexture.ReadPixels(new Rect(rect.x, rect.y, rect.width, rect.height), 0, 0);
readableTexture.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(renderTex);
return readableTexture;
}
private Color[] Resize(Color[] colors, int sourceWidth, int sourceHeight, int targetWidth, int targetHeight)
{
var ret = new Color[targetWidth * targetHeight];
var ratioX = 1.0f / ((float)targetWidth / (sourceWidth - 1));
var ratioY = 1.0f / ((float)targetHeight / (sourceWidth - 1));
for (var y = 0; y < targetHeight; y++)
{
var yFloor = Mathf.FloorToInt(y * ratioY);
for (var x = 0; x < targetWidth; x++)
{
var xFloor = Mathf.FloorToInt(x * ratioX);
var c1 = colors[xFloor * sourceHeight + yFloor];
var c2 = colors[xFloor * sourceHeight + yFloor];
var c3 = colors[xFloor * sourceHeight + yFloor + 1];
var c4 = colors[(xFloor + 1) * sourceHeight + yFloor + 1];
var xLerp = x * ratioX - xFloor;
var yLerp = y * ratioY - yFloor;
var top = Color.Lerp(c1, c2, xLerp);
var bottom = Color.Lerp(c3, c4, xLerp);
ret[x * targetHeight + y] = Color.Lerp(top, bottom, yLerp);
}
}
return ret;
}
}