Polygon sometimes not drawing when using path filled with PolygonPath.AddPoints

Avatar
  • updated
  • Fixed

Description:

When using PolygonPath.AddPoints(List<Vector2>) and attempting to use the created PolygonPath in a call to Draw.Polygon, in some cases a mesh will not be created.

Repro steps:

  1. Create a game object with the below ImmediateModeShapeDrawer (under Problem case)
  2. You may need to run in the editor for the Awake to be called
  3. Observe that the Polyline draws properly, but the Polygon does not.

Observations:

It appears in PointPath.cs under AddPoints(IEnumerable<T>), the meshDirty flag is not set to true anywhere in the function.

Problem case:

using Shapes;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class MissingPolygonMesh : ImmediateModeShapeDrawer
{
    const float TAU = Mathf.PI * 2f;
    public float radius = 5f;
    public float lineThickness = 0.25f;

    private PolylinePath linePath = null;
    private PolygonPath polygonPath = null;

    private void Awake()
    {
        const int count = 20;
        List<PolylinePoint> linePoints = new List<PolylinePoint>();
        List<Vector2> polygonPoints = new List<Vector2>();

        polygonPoints.Add(Vector2.zero);
        linePoints.Add(new PolylinePoint(Vector2.zero));

        for (int i = 1; i < count; ++i)
        {
            float t = (float)i / count;
            Vector2 point = new Vector2(Mathf.Cos(t * TAU) * radius, Mathf.Sin(t * TAU) * radius);
            polygonPoints.Add(point);
            linePoints.Add(new PolylinePoint(point));
        }

        linePath = new PolylinePath();
        linePath.AddPoints(linePoints);

        polygonPath = new PolygonPath();
        polygonPath.AddPoints(polygonPoints);
    }

    void OnDispose()
    {
        if (linePath != null) linePath.Dispose();
        if (polygonPath != null) polygonPath.Dispose();

        linePath = null;
        polygonPath = null;
    }

    public override void DrawShapes(Camera cam)
    {
        using (Draw.Command(cam))
        {
            Draw.PushMatrix();
            Draw.ApplyMatrix(transform.localToWorldMatrix);
            {
                if (polygonPath != null)
                {
                    // This should fill out the center of the Pac Man, but does not!
                    Draw.Polygon(polygonPath, PolygonTriangulation.EarClipping, Color.yellow);
                }
                if (linePath != null)
                {
                    Draw.Polyline(linePath, true, 1.0f, Color.black);
                }
            }
            Draw.PopMatrix();
        }
    }
}
Reporting a bug? please specify Unity version:
2020.2.3f1
Reporting a bug? please specify Shapes version:
4.0.2
Reporting a bug? please specify Render Pipeline:
Built-in render pipeline
Pinned replies
Avatar
Freya Holmér creator
  • Answer
  • Fixed

polylines and polygons have undergone a refactor due to a different bug, and it seems like this issue was fixed as a side effect!



not that it's related to the bug but, generally it's good practice to initialize your polylines in OnEnable, and dispose in OnDisable, that way it's guaranteed to never be null unexpectedly, and no meshes will leak. OnDisposed doesn't exist in game objects, so the meshes in your examples wouldn't actually get disposed, unless you call that function manually somewhere

Avatar
Freya Holmér creator
  • Answer
  • Fixed

polylines and polygons have undergone a refactor due to a different bug, and it seems like this issue was fixed as a side effect!



not that it's related to the bug but, generally it's good practice to initialize your polylines in OnEnable, and dispose in OnDisable, that way it's guaranteed to never be null unexpectedly, and no meshes will leak. OnDisposed doesn't exist in game objects, so the meshes in your examples wouldn't actually get disposed, unless you call that function manually somewhere

Avatar
belbeeno
Quote from Freya Holmér

polylines and polygons have undergone a refactor due to a different bug, and it seems like this issue was fixed as a side effect!



not that it's related to the bug but, generally it's good practice to initialize your polylines in OnEnable, and dispose in OnDisable, that way it's guaranteed to never be null unexpectedly, and no meshes will leak. OnDisposed doesn't exist in game objects, so the meshes in your examples wouldn't actually get disposed, unless you call that function manually somewhere

Cool!  And thanks for the advice!