using UnityEngine; // Shapes © Freya Holmér - https://twitter.com/FreyaHolmer/ // Website & Documentation - https://acegikmo.com/shapes/ namespace Shapes { /// A Line segment shape component [ExecuteAlways] [AddComponentMenu( "Shapes/Line" )] public partial class Line : ShapeRenderer, IDashable { /// The color modes for line shapes public enum LineColorMode { /// A single color across the whole line Single, /// Separate start and end colors Double } /// Get or set the start/end point by index (0 = start, 1 = end) public Vector3 this[ int i ] { get => i > 0 ? End : Start; set => _ = i > 0 ? End = value : Start = value; } // also called alignment for 2D lines [SerializeField] LineGeometry geometry = LineGeometry.Billboard; /// Get or set the type of geometry used (flat, billboarded, volumetric) public LineGeometry Geometry { get => geometry; set { geometry = value; SetIntNow( ShapesMaterialUtils.propAlignment, (int)geometry ); UpdateMesh( true ); UpdateMaterial(); ApplyProperties(); } } [SerializeField] LineColorMode colorMode = LineColorMode.Single; /// Whether or not to use one a single color or two colors, one at each end of the line public LineColorMode ColorMode { get => colorMode; set => SetColorNow( ShapesMaterialUtils.propColorEnd, ( colorMode = value ) == LineColorMode.Double ? colorEnd : base.Color ); } /// The color of this shape. The alpha channel is used for opacity/intensity in all blend modes public override Color Color { get => color; set { SetColor( ShapesMaterialUtils.propColor, color = value ); SetColorNow( ShapesMaterialUtils.propColorEnd, colorEnd = value ); } } /// The color to use at the start of the line (when ColorMode is set to Double) public Color ColorStart { get => color; set => SetColorNow( ShapesMaterialUtils.propColor, color = value ); } [SerializeField] [ShapesColorField( true )] Color colorEnd = Color.white; /// The color to use at the end of the line (when ColorMode is set to Double) public Color ColorEnd { get => colorEnd; set => SetColorNow( ShapesMaterialUtils.propColorEnd, colorEnd = value ); } [SerializeField] Vector3 start = Vector3.zero; /// The start point of this line in local space public Vector3 Start { get => start; set => SetVector3Now( ShapesMaterialUtils.propPointStart, start = value ); } [SerializeField] Vector3 end = Vector3.right; /// The endpoint of this line in local space public Vector3 End { get => end; set => SetVector3Now( ShapesMaterialUtils.propPointEnd, end = value ); } [SerializeField] float thickness = 0.125f; /// The thickness of this line in the given ThicknessSpace public float Thickness { get => thickness; set { SetFloatNow( ShapesMaterialUtils.propThickness, thickness = value ); if( dashed && dashStyle.space == DashSpace.Relative ) SetAllDashValues( now: true ); } } [SerializeField] ThicknessSpace thicknessSpace = Shapes.ThicknessSpace.Meters; /// The space in which Thickness is defined public ThicknessSpace ThicknessSpace { get => thicknessSpace; set => SetIntNow( ShapesMaterialUtils.propThicknessSpace, (int)( thicknessSpace = value ) ); } [SerializeField] LineEndCap endCaps = LineEndCap.Round; /// What end caps to use public LineEndCap EndCaps { get => endCaps; set { endCaps = value; UpdateMaterial(); } } private protected override void SetAllMaterialProperties() { SetVector3( ShapesMaterialUtils.propPointStart, start ); SetVector3( ShapesMaterialUtils.propPointEnd, end ); SetFloat( ShapesMaterialUtils.propThickness, thickness ); SetInt( ShapesMaterialUtils.propThicknessSpace, (int)thicknessSpace ); SetInt( ShapesMaterialUtils.propAlignment, (int)geometry ); SetColor( ShapesMaterialUtils.propColorEnd, colorMode == LineColorMode.Double ? colorEnd : base.Color ); SetAllDashValues( now: false ); } private protected override Bounds GetBounds_Internal() { // presume 0 world space padding when pixels or noots are used float padding = thicknessSpace == ThicknessSpace.Meters ? thickness : 0f; Vector3 center = ( start + end ) / 2f; Vector3 size = ShapesMath.Abs( start - end ) + new Vector3( padding, padding, padding ); return new Bounds( center, size ); } private protected override Material[] GetMaterials() => new[] { ShapesMaterialUtils.GetLineMat( geometry, endCaps )[BlendMode] }; private protected override Mesh GetInitialMeshAsset() => ShapesMeshUtils.GetLineMesh( geometry, endCaps, detailLevel ); internal override bool HasDetailLevels => true; private protected override void ShapeClampRanges() { thickness = Mathf.Max( 0, thickness ); DashSpacing = DashSpace == DashSpace.FixedCount ? Mathf.Clamp01( DashSpacing ) : Mathf.Max( 0f, DashSpacing ); } } }