void SetupTexture() { _boundsMinX = float.MaxValue; _boundsMinY = float.MaxValue; _boundsMaxX = float.MinValue; _boundsMaxY = float.MinValue; SpriteRendererExt.GetActiveBounds(sprite, ref _boundsMinX, ref _boundsMinY, ref _boundsMaxX, ref _boundsMaxY, includeChildren, ShouldIgnoreSprite); int padding = outlineSize * 2; int width = Mathf.CeilToInt((_boundsMaxX - _boundsMinX) * sprite.sprite.pixelsPerUnit) + padding; int height = Mathf.CeilToInt((_boundsMaxY - _boundsMinY) * sprite.sprite.pixelsPerUnit) + padding; if (!texture) { texture = new Texture2D(width, height, TextureFormat.RGBA32, false); texture.filterMode = sprite.sprite.texture.filterMode; texture.wrapMode = sprite.sprite.texture.wrapMode; } else { texture.Resize(width, height); } }
public void Regenerate() { if (useExportedFrame != _cachedUseExportedFrame) { _shouldRegenerateMaterial = true; } if (!material || _shouldRegenerateMaterial) { string shaderName = useExportedFrame ? "Particles/Alpha Blended Premultiply" : "Sprites/Outline"; Shader shader = Shader.Find(shaderName); if (!shader) { LogError("Material cannot be created (\"{0}\" shader is missing)", shaderName); // NOTE: This should never happen. return; } material = new Material(shader); texture = null; // Force the texture to be recreated. _cachedUseExportedFrame = useExportedFrame; _shouldRegenerateMaterial = false; } if (!outline) { TryGetOutline(); if (!outline) { outline = new GameObject("Outline"); } } outline.transform.SetParent(transform, false); TryGetSprite(); if (!sprite) { return; } if (spriteRenderer && !outlineSpriteRenderer) { outlineSpriteRenderer = outline.AddComponent <SpriteRenderer> (); } else if (image && !outlineImage) { outlineImage = outline.AddComponent <Image> (); } Vector3 cachedPosition = transform.position; Quaternion cachedRotation = transform.rotation; Vector3 cachedScale = transform.localScale; transform.position = Vector3.zero; transform.rotation = Quaternion.identity; _scale.x = transform.localScale.x / transform.lossyScale.x; _scale.y = transform.localScale.y / transform.lossyScale.y; _scale.z = transform.localScale.z / transform.lossyScale.z; transform.localScale = _scale; if (outlineSpriteRenderer) { outlineSpriteRenderer.material = material; } else if (outlineImage) { outlineImage.material = material; } _boundsMinX = float.MaxValue; _boundsMinY = float.MaxValue; _boundsMaxX = float.MinValue; _boundsMaxY = float.MinValue; if (outlineSpriteRenderer) { SpriteRendererExt.GetActiveBounds(spriteRenderer, ref _boundsMinX, ref _boundsMinY, ref _boundsMaxX, ref _boundsMaxY, includeChildren, ShouldIgnoreSprite); } else if (outlineImage) { ImageExt.GetActiveBounds(image, ref _boundsMinX, ref _boundsMinY, ref _boundsMaxX, ref _boundsMaxY, includeChildren, ShouldIgnoreSprite); } if (_boundsMinX == float.MaxValue) { SetTransformValues(cachedPosition, cachedRotation, cachedScale); LogError("Outline cannot be created (there are no active sprites)"); return; } if (useExportedFrame) { string sanitizedName = GetSanitizedName((customFrameName != string.Empty) ? customFrameName : name); string resourcePath = sanitizedName + RESOURCE_EXT; texture = Resources.Load <Texture2D> (resourcePath); if (!texture) { SetTransformValues(cachedPosition, cachedRotation, cachedScale); string texturePath = RESOURCE_DIR + sanitizedName + IMAGE_EXT; LogError("Exported frame \"{0}\" not found (disable \"Use Exported Frame\" and press \"Export\" to fix)", texturePath); return; } } else { SetupTexture(); ClearTexture(); _sortingSpriteRenderer = null; try { FillTexture(gameObject, sprite); } catch (UnityException e) { SetTransformValues(cachedPosition, cachedRotation, cachedScale); int startIndex = e.Message.IndexOf("'"); int endIndex = e.Message.IndexOf("'", startIndex + 1) + 1; string textureName = e.Message.Substring(startIndex, endIndex - startIndex); LogError("Texture {0} is not readable (turn on \"Read/Write Enabled\" in its Import Settings to fix)", textureName); return; } texture.Apply(); material.SetInt("_Size", size); material.SetInt("_BlurSize", blurSize); material.SetColor("_Color", color); material.SetFloat("_BlurAlphaMultiplier", blurAlphaMultiplier); material.SetFloat("_BlurAlphaChoke", blurAlphaChoke); material.SetInt("_InvertBlur", invertBlur ? 1 : 0); material.SetFloat("_AlphaThreshold", alphaThreshold); material.SetInt("_Buffer", buffer); } _textureRect.width = texture.width; _textureRect.height = texture.height; _anchor.x = (sprite.pivot.x + GetOffsetX(gameObject, sprite)) / texture.width; _anchor.y = (sprite.pivot.y + GetOffsetY(gameObject, sprite)) / texture.height; Sprite outlineSprite = Sprite.Create(texture, _textureRect, _anchor, sprite.pixelsPerUnit, 0, SpriteMeshType.FullRect); if (outlineSpriteRenderer) { outlineSpriteRenderer.sprite = outlineSprite; } else if (outlineImage) { outlineImage.sprite = outlineSprite; float pixelsPerUnit = (image.canvas.referencePixelsPerUnit / sprite.pixelsPerUnit); _anchor.x = -(GetOffsetX(gameObject, sprite) + sprite.textureRect.width / 2 - texture.width / 2f) * pixelsPerUnit; _anchor.y = -(GetOffsetY(gameObject, sprite) + sprite.textureRect.height / 2 - texture.height / 2f) * pixelsPerUnit; outlineImage.rectTransform.anchoredPosition = _anchor; outlineImage.SetNativeSize(); outlineImage.canvasRenderer.Clear(); } SetTransformValues(cachedPosition, cachedRotation, cachedScale); SortOutline(); // NOTE: Must sort after resetting the transform values to calculate the correct Z-axis value. if (Application.isPlaying && isAnimated) { if (useExportedFrame) // Do not cache the exported frame as animations are not currently supported. { return; } Texture2D textureClone = Texture2D.Instantiate(texture); Sprite outlineSpriteClone = Sprite.Create(textureClone, _textureRect, _anchor, sprite.pixelsPerUnit, 0, SpriteMeshType.FullRect); int spriteFrameId = sprite.GetInstanceID(); _cachedOutlineSprites [spriteFrameId] = outlineSpriteClone; if (outlineImage) { _cachedOutlineAnchors [spriteFrameId] = outlineImage.rectTransform.anchoredPosition; } } }