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=0" 같은 형태 } private void InitTexture() { baseTex = Resources.Load("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; } }