2D SpriteShape Edits

Hi,

I’m trying to save/load/edit some kind of areas for a game. These areas are 2D sprite shapes.

I managed to save the spline control points infos (pos & some other properties), and load them (I instanciate a default spriteshape from my prefabs, clear the spline and insert the saved points)

Here’s the loading code :

    //This is applied to a sprite shape that just got instanciated.
    void UpdatePoints(List<ZonePoint> points)
    {
        spline.Clear(); //this is the SpriteShapeController spline
        for (int i = 0; i < points.Count; i++)
        {
            spline.InsertPointAt(i, points[i].pos);
            spline.SetCorner(i, true);
            spline.SetHeight(i, points[i].height);
            spline.SetTangentMode(i, points[i].tangentMode);
            spline.SetLeftTangent(i, points[i].leftTangent);
            spline.SetRightTangent(i, points[i].rightTangent);
            spline.SetSpriteIndex(i, points[i].spriteIndex);
        }
    }

This works fine, the shape gets generated with points located where we saved them.

Except i still have one problem :
When i want to (after loading the shape) manually edit the sprite shape points, the shape editing gets broken ;

  • spline points are reset to pos (0,0) on moving, and are stuck there
  • trying to add a point between 2 others, reset the 2 other points to (0,0), and get stuck also

it looks like a serialization problem or something ? i tried to hack into the package to add the following line in the Initialize() method of SpriteShapeEditorTool.cs, thinking it would update the points data, but it did nothing :

serializedObject.Update();

Any advice on how to script-edit a sprite shape, and then manual-edit the same shape ?

When an Object is edited through script, it must also be saved if required to be persistent. For example, the following sample sets the spline points and saves the object in Edit mode.

using UnityEngine;
using UnityEditor;
using UnityEngine.U2D;

public class SetSpriteShape : MonoBehaviour
{
    [MenuItem("Assets/Customize SpriteShape")]
    static void UpdatePoints()
    {
        var go = Selection.activeGameObject;
        if (go == null) return;

        var spline = go.GetComponent<SpriteShapeController>().spline;
        spline.Clear();

        var points = new Vector2[4] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) };

        for (int i = 0; i < points.Length; i++)
        {
            spline.InsertPointAt(i, points[i]);
            spline.SetCorner(i, true);
        }

        EditorUtility.SetDirty(go);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
        SceneView.RepaintAll();
    }
}

You can then manually edit the SpriteShape object.

Well, this does not work for my setup, as is your script sample.
It only works at initial shape creation, where everything is already working fine.

But once the playmode is reloaded, new shapes are instanciated, splines cleared, and saved spline points are inserted, we are back to square one.

public void UpdatePoints(List<ZonePoint> points)
{
    spline.Clear();
    for (int i = 0; i < points.Count; i++)
    {
        spline.InsertPointAt(i, points[i].pos);
        spline.SetCorner(i, true);
        spline.SetHeight(i, points[i].height);
        spline.SetTangentMode(i, points[i].tangentMode);
        spline.SetLeftTangent(i, points[i].leftTangent);
        spline.SetRightTangent(i, points[i].rightTangent);
        spline.SetSpriteIndex(i, points[i].spriteIndex);
    }

    EditorUtility.SetDirty(gameObject); //gameObject = the spriteshape gameobject, which has a spriteshapecontroller
    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();
    SceneView.RepaintAll();
}

Is this supposed to work on 9.0.5 ?

Changes made to GameObjects during Playmode are not applied when exiting. You probably need to store the changes and re-apply it.

If this is not the case, please submit a bug-report or repro project to help us analyze the issue better. Thanks.

Alright i found my problem : i’m stupid.

i was trying to apply a localScale to the shape, but with a Vector2.
This was setting the shape’s scale.Z to 0, which is what was breaking the manual editing of points.

Well, sorry about that, and thank you for taking the time !