Get/Set Sprite Custom Outline from script?

I’d like to get/set custom outlines (like in Sprite Editor) from a script in Editor.

From the meta file:
6338901--704058--Capture - Copy.PNG

I can modify other properties of spritesheet with the TextureImporter Settings/Properties, but I’m struggling to find the spot for adjusting the outline. If there’s no public way to do this, is modifying the .meta file directly dangerous?

Hi @Lo-renzo ,

Modifying the outline is not exposed to the public API for you to change it directly, as you can see here: Unity - Scripting API: SpriteMetaData

However, as you mentioned, it’s possible to change it directly by modifying the meta file.

You can find a working example of how you can do it here: Setting custom sprite outline via script/asset postprocessor

Using this specific method in the Editor is not dangerous if you use the proper values :wink:

Good luck with it!

Hey @DiegoDePalacio_1 , and why is this not exposed in the public API? Seems like an unnecessarily complex workaround for something that shouldn’t be difficult to achieve :frowning:

@Lo-renzo , @Joseguepardo , you should be able to modify the Sprite outline using ISpriteOutlineDataProvider API as shown in this documentation page.

Do we know of any other outline implementations done except for the Unity one?
For example, in my case I’m using 1024x1024 textures which I’d like to use an outline for. The built-in Unity outline creates too many verts (189 tris, 184 verts), which in my case would suffice with just 10 or 15 verts to remove most of the transparent area.
Would be great if there were some implementations lying around!

Hello mate,

Let me try to help. (Unity version: 2020.3.23f1)
Spoiler: fail

Theoretically, this can be done through ISpriteOutlineDataProvider.SetOutlines from UnityEditor.U2D.Sprites namespace. Here’s snippet on how it should be possibly done:

Texture 2D target;

var spriteDataProviderFactories = new SpriteDataProviderFactories();
var dataProvider = spriteDataProviderFactories.GetSpriteEditorDataProviderFromObject(target);

GUID targetGUID = new GUIDAssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(target))

List<Vector2[]> points = new List<Vector2[]>
{
    new Vector2[]
    {
        new Vector2(1,1),
        new Vector2(2,2),
        new Vector2(3,3)
    }
};

var outlineProvider = dataProvider.GetDataProvider<ISpriteOutlineDataProvider>();
outlineProvider.SetOutlines(targetGUID, points);

As spoiler said, this will give error inside ISpriteOutlineDataProvider.SetOutlines saying there’s a null error.

Personal solution: edit metadata directly.

The documentation gives too few details, so based on the documentation and the code given by @Solihin100, I’ve summarized the correct way to use it:

Texture 2D target;

var spriteDataProviderFactories = new SpriteDataProviderFactories();
var dataProvider = spriteDataProviderFactories.GetSpriteEditorDataProviderFromObject(target);
dataProvider.InitSpriteEditorDataProvider(); // !!important!! If it is not initialized, then the null error will occur at ISpriteOutlineDataProvider.SetOutlines
var outlineProvider = dataProvider.GetDataProvider<ISpriteOutlineDataProvider>();
var textureProvider = dataProvider.GetDataProvider<ITextureDataProvider>();

// the texture asset's sprite mode is set to multiple, so there will be a few spriteRects
foreach (var rect in dataProvider.GetSpriteRects())
{
    var guid = rect.spriteID; // !!important!! guid is not asset's guid, but spriteRect's guid
    List<Vector2[]> points = new List<Vector2[]>
    {
        new Vector2[]
        {
            new Vector2(1,1),
            new Vector2(2,2),
            new Vector2(3,3)
        },
        new Vector2[]
        {
            new Vector2(2,1),
            new Vector2(2,2),
            new Vector2(1,2),
        } // Maybe you want two outline in one sprite
    };
        // set the outline for each sprite, instead of setting it for the whole texture
        outlineProvider.SetOutlines(guid, outlines);
    }
}

dataProvider.Apply(); // !!important!!