예제 #1
0
    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);
        }
    }
예제 #2
0
    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;
            }
        }
    }