2017-06-22 07:54:02 +08:00
/// Credit Alastair Aitchison
/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/123/uilinerenderer-issues-with-specifying
namespace UnityEngine.UI.Extensions
{
2017-06-26 05:36:09 +08:00
[AddComponentMenu("UI/Extensions/UI Line Connector")]
2017-06-22 07:54:02 +08:00
[RequireComponent(typeof(UILineRenderer))]
[ExecuteInEditMode]
public class UILineConnector : MonoBehaviour
{
// The elements between which line segments should be drawn
public RectTransform [ ] transforms ;
2021-05-11 01:38:31 +08:00
private Vector3 [ ] previousPositions ;
2024-10-02 16:03:06 +08:00
private Vector3 previousLrPos ;
2024-10-02 18:57:57 +08:00
private Vector3 previousGlobalScale ;
2017-06-22 07:54:02 +08:00
private RectTransform rt ;
private UILineRenderer lr ;
private void Awake ( )
{
rt = GetComponent < RectTransform > ( ) ;
lr = GetComponent < UILineRenderer > ( ) ;
}
2024-10-02 18:57:57 +08:00
private void OnEnable ( )
{
if ( transforms = = null | | transforms . Length < 1 )
{
return ;
}
CalculateLinePoints ( ) ;
}
private void Update ( )
2017-06-22 07:54:02 +08:00
{
2024-10-02 16:03:06 +08:00
if ( lr . RelativeSize )
{
Debug . LogWarning ( "While using UILineConnector, UILineRenderer should not use relative size, so that even if this RectTransform has a zero-size Rect, the positions of the points can still be calculated" ) ;
lr . RelativeSize = false ;
}
2017-06-22 07:54:02 +08:00
if ( transforms = = null | | transforms . Length < 1 )
{
return ;
}
2024-10-02 16:03:06 +08:00
// Get world position of UILineRenderer
Vector3 lrWorldPos = rt . position ;
/ * Performance check to only redraw when the child transforms move ,
or the world position of UILineRenderer moves * /
bool updateLine = lrWorldPos ! = previousLrPos ;
2024-10-02 18:57:57 +08:00
updateLine = rt . lossyScale ! = previousGlobalScale ;
2024-10-02 16:03:06 +08:00
if ( ! updateLine & & previousPositions ! = null & & previousPositions . Length = = transforms . Length )
2017-08-05 03:36:25 +08:00
{
for ( int i = 0 ; i < transforms . Length ; i + + )
{
2023-06-18 01:33:22 +08:00
if ( transforms [ i ] = = null )
{
continue ;
}
2021-05-11 01:38:31 +08:00
if ( ! updateLine & & previousPositions [ i ] ! = transforms [ i ] . position )
2017-08-05 03:36:25 +08:00
{
updateLine = true ;
2024-10-02 16:03:06 +08:00
break ;
2017-08-05 03:36:25 +08:00
}
}
2024-10-02 16:03:06 +08:00
}
2024-10-02 18:57:57 +08:00
if ( ! updateLine ) return ;
2017-06-22 07:54:02 +08:00
2024-10-02 16:03:06 +08:00
// Calculate delta from the local position
2024-10-02 18:57:57 +08:00
CalculateLinePoints ( ) ;
//save previous states
previousLrPos = lrWorldPos ;
previousGlobalScale = rt . lossyScale ;
previousPositions = new Vector3 [ transforms . Length ] ;
2017-06-22 07:54:02 +08:00
for ( int i = 0 ; i < transforms . Length ; i + + )
{
2023-06-18 01:33:22 +08:00
if ( transforms [ i ] = = null )
{
continue ;
}
2024-10-02 18:57:57 +08:00
previousPositions [ i ] = transforms [ i ] . position ;
2017-06-22 07:54:02 +08:00
}
2024-10-02 18:57:57 +08:00
}
2017-06-22 07:54:02 +08:00
2024-10-02 18:57:57 +08:00
private void CalculateLinePoints ( )
{
Vector2 [ ] points = new Vector2 [ transforms . Length ] ;
2017-08-05 03:36:25 +08:00
for ( int i = 0 ; i < transforms . Length ; i + + )
{
2023-06-18 01:33:22 +08:00
if ( transforms [ i ] = = null )
{
continue ;
}
2024-10-02 18:57:57 +08:00
var offsetPos = rt . InverseTransformPoint ( transforms [ i ] . position ) ;
points [ i ] = new Vector2 ( offsetPos . x , offsetPos . y ) ;
2017-08-05 03:36:25 +08:00
}
2024-10-02 16:03:06 +08:00
2024-10-02 18:57:57 +08:00
// And assign the converted points to the line renderer
lr . Points = points ;
lr . RelativeSize = false ;
lr . drivenExternally = true ;
2017-06-22 07:54:02 +08:00
}
}
}