using System; using System.Globalization; using UnityEngine; namespace GeometryTD.CustomUtility { public static class TowerIconComposeUtility { public static Sprite Compose( Sprite muzzleSprite, Color muzzleColor, Sprite bearingSprite, Color bearingColor, Sprite baseSprite, Color baseColor) { if (muzzleSprite == null || bearingSprite == null || baseSprite == null) { return null; } Sprite referenceSprite = muzzleSprite ?? bearingSprite ?? baseSprite; if (referenceSprite == null) { return null; } int width = Mathf.RoundToInt(referenceSprite.rect.width); int height = Mathf.RoundToInt(referenceSprite.rect.height); if (width <= 0 || height <= 0) { return null; } return ComposeWithRenderTexture( muzzleSprite, muzzleColor, bearingSprite, bearingColor, baseSprite, baseColor, width, height, referenceSprite); } public static string BuildCacheKey( long muzzleId, long bearingId, long baseId, Color muzzleColor, Color bearingColor, Color baseColor) { return string.Format( CultureInfo.InvariantCulture, "v2|{0}|{1}|{2}|{3}|{4}|{5}", muzzleId, bearingId, baseId, ToColorKey(muzzleColor), ToColorKey(bearingColor), ToColorKey(baseColor)); } private static Sprite ComposeWithRenderTexture( Sprite muzzleSprite, Color muzzleColor, Sprite bearingSprite, Color bearingColor, Sprite baseSprite, Color baseColor, int width, int height, Sprite referenceSprite) { RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32); RenderTexture previous = RenderTexture.active; try { RenderTexture.active = rt; GL.PushMatrix(); GL.LoadPixelMatrix(0f, width, 0f, height); GL.Clear(true, true, Color.clear); DrawSpriteToRenderTarget(baseSprite, baseColor, width, height); DrawSpriteToRenderTarget(bearingSprite, bearingColor, width, height); DrawSpriteToRenderTarget(muzzleSprite, muzzleColor, width, height); GL.PopMatrix(); Texture2D composedTexture = new Texture2D(width, height, TextureFormat.RGBA32, false); composedTexture.ReadPixels(new Rect(0f, 0f, width, height), 0, 0); composedTexture.Apply(false, false); return CreateSprite(composedTexture, referenceSprite); } catch (Exception) { return null; } finally { RenderTexture.active = previous; RenderTexture.ReleaseTemporary(rt); } } private static void DrawSpriteToRenderTarget(Sprite sprite, Color color, int width, int height) { if (sprite == null || sprite.texture == null) { return; } Rect textureRect = sprite.textureRect; Texture texture = sprite.texture; Rect uvRect = new Rect( textureRect.x / texture.width, textureRect.y / texture.height, textureRect.width / texture.width, textureRect.height / texture.height); Graphics.DrawTexture(new Rect(0f, 0f, width, height), texture, uvRect, 0, 0, 0, 0, color); } private static Sprite CreateSprite(Texture2D texture, Sprite referenceSprite) { if (texture == null || referenceSprite == null) { return null; } float width = Mathf.Max(1f, referenceSprite.rect.width); float height = Mathf.Max(1f, referenceSprite.rect.height); Vector2 pivot = new Vector2(referenceSprite.pivot.x / width, referenceSprite.pivot.y / height); return Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), pivot, referenceSprite.pixelsPerUnit); } private static string ToColorKey(Color color) { Color32 c = color; return c.r.ToString("X2", CultureInfo.InvariantCulture) + c.g.ToString("X2", CultureInfo.InvariantCulture) + c.b.ToString("X2", CultureInfo.InvariantCulture) + c.a.ToString("X2", CultureInfo.InvariantCulture); } } }