using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Serialization; // Shapes © Freya Holmér - https://twitter.com/FreyaHolmer/ // Website & Documentation - https://acegikmo.com/shapes/ namespace Shapes { /// A Polygon shape component [ExecuteAlways] [AddComponentMenu( "Shapes/Polygon" )] public partial class Polygon : ShapeRenderer, IFillable { #if UNITY_EDITOR /// "Please use points instead of PolyPoints - this one is deprecated" [Obsolete( "Please use " + nameof(points) + " instead - this one is deprecated", error: true )] public List PolyPoints => points; #endif /// /// IMPORTANT: if you modify this list, you need to set meshOutOfDate to true, otherwise your changes won't apply /// [FormerlySerializedAs( "polyPoints" )] [SerializeField] public List points = new List() { new Vector2( 1f, 0f ), new Vector2( 0.5f, 0.86602545f ), new Vector2( -0.5f, 0.8660254f ), new Vector2( -1f, 0f ), new Vector2( -0.5f, -0.86602545f ), new Vector2( 0.5f, -0.86602545f ) }; // also called alignment [SerializeField] PolygonTriangulation triangulation = PolygonTriangulation.EarClipping; /// What triangulation mode to use for this polygon public PolygonTriangulation Triangulation { get => triangulation; set { triangulation = value; meshOutOfDate = true; } } /// The number of points in this polygon public int Count => points.Count; /// Get or set a polygon point by index public Vector2 this[ int i ] { get => points[i]; set { points[i] = value; meshOutOfDate = true; } } /// Set a polygon point position by index public void SetPointPosition( int index, Vector2 position ) { if( index < 0 || index >= Count ) throw new IndexOutOfRangeException(); points[index] = position; meshOutOfDate = true; } /// Sets all points of this polygon to the input points public void SetPoints( IEnumerable points ) { this.points.Clear(); AddPoints( points ); } /// Sets all points of this polygon to the input points public void AddPoints( IEnumerable points ) { this.points.AddRange( points ); meshOutOfDate = true; } /// Adds a point to this polygon public void AddPoint( Vector2 point ) { points.Add( point ); meshOutOfDate = true; } private protected override bool UseCamOnPreCull => true; internal override void CamOnPreCull() { if( meshOutOfDate ) { meshOutOfDate = false; UpdateMesh( force: true ); } } #if UNITY_EDITOR [ContextMenu( "Reverse Points [DEBUG ONLY]" )] void ReversePoints() { points.Reverse(); meshOutOfDate = true; } [ContextMenu( "Shift Points Forward [DEBUG ONLY]" )] void ShiftForward() { List newPts = new List(); newPts.Add( points[points.Count - 1] ); for( int i = 0; i < points.Count - 1; i++ ) newPts.Add( points[i] ); points = newPts; meshOutOfDate = true; } #endif private protected override void SetAllMaterialProperties() => SetFillProperties(); internal override bool HasScaleModes => false; internal override bool HasDetailLevels => false; private protected override Material[] GetMaterials() => new[] { ShapesMaterialUtils.matPolygon[BlendMode] }; private protected override MeshUpdateMode MeshUpdateMode => MeshUpdateMode.SelfGenerated; private protected override void GenerateMesh() => ShapesMeshGen.GenPolygonMesh( Mesh, points, triangulation ); private protected override Bounds GetBounds_Internal() { if( points.Count < 2 ) return default; Vector3 min = Vector3.one * float.MaxValue; Vector3 max = Vector3.one * float.MinValue; foreach( Vector3 pt in points ) { min = Vector3.Min( min, pt ); max = Vector3.Max( max, pt ); } return new Bounds( ( max + min ) * 0.5f, max - min ); } } }