Search Unity

SpriteShape: modifying the shape at runtime -- the sprite does not show

Discussion in '2D Experimental Preview' started by DerickTP, Nov 21, 2018.

  1. DerickTP

    DerickTP

    Joined:
    Jul 28, 2014
    Posts:
    8
    EDIT: By setting spline quality to medium in the spriteshapecontroller inspector, it seems to work... But i still have to go to the scene window to show the mesh the first time. However the collider is there and my character is floating in thin air...

    Hi there,

    I have beed trying to use the Sprite shape package to make some kind of platformer like the sort of Alto. My idea was to build a few sprite shape controllers ahead of time and repurpose these as needed. So here is what I did:
    - at startup I instanciate 3-4 game objects with sprite shapes and colliders attached (one edge collider for the geometry and one box trigger collider for other purposes). I then modify the shapes as needed to fit my needs.
    - When the object becomes invisible, it is 'repurposed', i.e. I modify the spline in order to continue the path at the end of the currently generated path.

    Basically, I see the first repurposing instance for each object in the logs, but when I reach the end of the path, the path is empty. However the colliders are there, cause my object goes on. By going to the scene window and dezooming, I see the objects pop up on the screen and in my game window... I even tried to delete the objects and recreate them instead and I had no luck there... Here is a link to a gif showing the problem I hope :

    http://i.imgur.com/GB6nfx6.gifv

    And here is the code I use:
    Class that creates the objects and modify the spline
    Code (CSharp):
    1. public class WorldBuilding : MonoBehaviour
    2. {
    3.     public static WorldBuilding instance = null;
    4.     public SpriteShapeController prefab;
    5.  
    6.     [Header("World generic data")]
    7.     public float m_fSectionSize = 10f;
    8.     public float m_fSectionHeight = 100f;
    9.     [Range(3,10)]
    10.     public int m_iNumberOfPreloadedSections = 3;
    11.  
    12.     SpriteShapeController[] controllers;
    13.     int nextSection;
    14.  
    15.     Queue<int> repurposeList = new Queue<int>();
    16.  
    17.     // Use this for initialization
    18.     void Start ()
    19.     {
    20.         if(instance ==null)
    21.         {
    22.             instance = this;
    23.         }
    24.         else
    25.         {
    26.             DestroyImmediate(gameObject);
    27.             return;
    28.         }
    29.         nextSection = m_iNumberOfPreloadedSections;
    30.         CreateShapes();
    31.     }
    32.  
    33.     void CreateShapes()
    34.     {
    35.         controllers = new SpriteShapeController[m_iNumberOfPreloadedSections];
    36.         for (int i = 0; i < m_iNumberOfPreloadedSections; ++i)
    37.         {
    38.             CreateShape(i, i, i == 0);
    39.         }
    40.     }
    41.  
    42.     void CreateShape(int idx, int sectionNumber, bool isFirst = false)
    43.     {
    44.         controllers[idx] = GameObject.Instantiate<SpriteShapeController>(prefab, transform);
    45.         controllers[idx].splineDetail = 32;
    46.  
    47.         MakePath(idx, sectionNumber, isFirst);
    48.     }
    49.  
    50.     void MakePath(int idx, int sectionNumber, bool first = false)
    51.     {
    52.         Spline s = controllers[idx].spline;
    53.         s.Clear();
    54.  
    55.         float startPos = sectionNumber * m_fSectionSize;
    56.         float endPos = (sectionNumber + 1) * m_fSectionSize;
    57.  
    58.         int offset = 0;
    59.         s.InsertPointAt(offset++, new Vector3(endPos, -m_fSectionHeight, 0));
    60.         s.InsertPointAt(offset++, new Vector3(startPos, -m_fSectionHeight, 0));
    61.  
    62.  
    63.         s.InsertPointAt(offset++, new Vector3(startPos, 0, 0));
    64.         if (!first)
    65.         {
    66.             s.SetTangentMode(offset - 1, ShapeTangentMode.Continuous);
    67.             s.SetLeftTangent(offset - 1, new Vector3(-1, 0, 0));
    68.             s.SetRightTangent(offset - 1, new Vector3(1, 0, 0));
    69.         }
    70.  
    71.         s.InsertPointAt(offset++, new Vector3(0.5f * (startPos + endPos), 2f, 0));
    72.         s.SetTangentMode(offset - 1, ShapeTangentMode.Continuous);
    73.         s.SetLeftTangent(offset - 1, new Vector3(-1, 0, 0));
    74.         s.SetRightTangent(offset - 1, new Vector3(1, 0, 0));
    75.  
    76.         s.InsertPointAt(offset++, new Vector3(endPos, 0, 0));
    77.         s.SetTangentMode(offset - 1, ShapeTangentMode.Continuous);
    78.         s.SetLeftTangent(offset - 1, new Vector3(-1, 0, 0));
    79.         s.SetRightTangent(offset - 1, new Vector3(1, 0, 0));
    80.  
    81.         //controllers[idx].BakeMesh(); // Gives an error on splinedetails which sould be between 4 and 32. Setting it right before this call does not change the problem.
    82.         //controllers[idx].spriteShapeRenderer.bounds.SetMinMax(new Vector3(startPos, -m_fSectionHeight, 0), new Vector3(endPos, m_fSectionHeight, 0));
    83.         controllers[idx].BakeCollider();
    84.  
    85.         BoxCollider2D box = controllers[idx].GetComponent<BoxCollider2D>();
    86.         box.size = new Vector2(m_fSectionSize, m_fSectionHeight * 2);
    87.         box.offset = new Vector2(0.5f * (startPos + endPos), 0);
    88.  
    89.         WorldSection section = controllers[idx].GetComponent<WorldSection>();
    90.         section.Index = idx;
    91.         section.WasInside = false;
    92.  
    93.         controllers[idx].gameObject.SetActive(true);
    94.     }
    95.  
    96.     public void Repurpose(int idx)
    97.     {
    98.         Debug.Log("Repurposing " + idx);
    99.         repurposeList.Enqueue(idx);
    100.     }
    101.  
    102.     // Update is called once per frame
    103.     void Update ()
    104.     {
    105.         RebuildPathAhead();
    106.     }
    107.  
    108.  
    109.     void RebuildPathAhead()
    110.     {
    111.         while(repurposeList.Count > 0)
    112.         {
    113.             int idx = repurposeList.Dequeue();
    114.             Debug.Log("Rebuild " + idx);
    115.             DestroyImmediate(controllers[idx].gameObject);
    116.             CreateShape(idx, nextSection++);
    117.             //MakePath(idx, nextSection++, false);
    118.         }
    119.     }
    120. }
    121.  
    Class that handles the becameinvisible part and is attached to the object that has the sprite shape controller component attached to it:
    Code (CSharp):
    1. public class WorldSection : MonoBehaviour
    2. {
    3.     int index;
    4.     public int Index
    5.     {
    6.         get { return index; }
    7.         set { index = value; }
    8.     }
    9.  
    10.     bool wasInside = false;
    11.     public bool WasInside
    12.     {
    13.         get { return wasInside; }
    14.         set { wasInside = value; }
    15.     }
    16.  
    17.     // Use this for initialization
    18.     void Start ()
    19.     {
    20.  
    21.     }
    22.  
    23.     // Update is called once per frame
    24.     void Update ()
    25.     {
    26.  
    27.     }
    28.  
    29.     private void OnTriggerStay2D(Collider2D collision)
    30.     {
    31.         //Debug.Log("Inside section");
    32.         wasInside = true;
    33.     }
    34.  
    35.     public void OnBecameInvisible()
    36.     {
    37.         Debug.Log("BecameInvisible");
    38.         if (!wasInside) return;
    39.         WorldBuilding.instance?.Repurpose(index);
    40.         gameObject.SetActive(false);
    41.     }
    42. }
    43.  
    Thanks for any help that you could give and ask me if you need more infos!.
     
    Last edited: Nov 22, 2018
  2. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    154
    @DerickTP Could you please file a bug report with a simple repro case ? We will take a look asap as it does look like a bug.
     
  3. DerickTP

    DerickTP

    Joined:
    Jul 28, 2014
    Posts:
    8
    Thanks, done it. Bug number is 1103327.
     
  4. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    154
    @DerickTP Thanks for submitting the bug report. While we investigate the issue (is most likely related to regarding Bounds), as a workaround, please try to modify the SpriteShape in the Prefab to be of much larger size. This should fix the issue. Please do let us know if this works.
     
    DerickTP likes this.
  5. DerickTP

    DerickTP

    Joined:
    Jul 28, 2014
    Posts:
    8
    Hi, thanks it seems to work by increasing the size of the sprite shape for now. Thanks for the responsivenes!