Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Need to Draw this a line using sprite

Discussion in '2D' started by raviraj_vdy, Oct 9, 2015.

  1. raviraj_vdy

    raviraj_vdy

    Joined:
    May 14, 2009
    Posts:
    309
    Hello Guys

    I need to draw a line as per the attached image using a sprite. I have also provide the sample sprite that needs to be used.

    Can anyone help me with the same.

    Thank you.
     

    Attached Files:

    bsks777 likes this.
  2. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    For fun I tried to solve this using sprites and scaling. It takes a bit of work to setup...

    First I imported your sprite; TracLine.png. I set Pixels Per Unit to 108, to make it one unit tall.

    I then sliced it into three parts called TopCap, Center, and BottomCap. TopCap and BottomCap being the half circles at the end and Center being the solid rectangle in the middle. I placed the pivot at top for TopCap and Center, and the BottomCap's pivot was set to bottom.

    I then created an empty gameobject and placed the new sprites into this. I rotated them 90 degrees. The TopCap was placed at (0, 0) and then I used vertex snap to line up the three sprites. This "recreated" your original sprite, but now its align with the X-axis. Since its Pixel Per Unit was 108, this makes the combined sprite one unit long.

    I then attached the script included below and it worked like a charm. If my explanation of the setup is hard to follow, I can always upload my project...

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DrawLine : MonoBehaviour
    5. {
    6.     public Vector2 start = Vector2.zero;
    7.     public Vector2 stop = Vector2.zero;
    8.  
    9.     private Transform topCap;
    10.     private Transform center;
    11.     private Transform bottomCap;
    12.  
    13.     private float topCapLength;
    14.     private float bottomCapLength;
    15.  
    16.     private float invCenterLength;
    17.  
    18.     private float minLength;
    19.  
    20.     void Start()
    21.     {
    22.         topCap = transform.FindChild("TopCap");
    23.         center = transform.FindChild("Center");
    24.         bottomCap = transform.FindChild("BottomCap");
    25.  
    26.         topCapLength = 2 * topCap.GetComponent<Renderer>().bounds.extents.x;
    27.         invCenterLength = 1 / (2 * center.GetComponent<Renderer>().bounds.extents.x);
    28.         bottomCapLength = 2 * bottomCap.GetComponent<Renderer>().bounds.extents.x;
    29.  
    30.         minLength = topCapLength + bottomCapLength;
    31.     }
    32.  
    33.     void Update()
    34.     {
    35.         // For testing purposes
    36.         if (Input.GetButton("Fire1"))
    37.         {
    38.             stop = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    39.         }
    40.  
    41.         Draw(start, stop);
    42.     }
    43.  
    44.     void Draw(Vector2 start, Vector2 stop)
    45.     {
    46.         Vector2 dir = stop - start;
    47.  
    48.         float length = dir.magnitude;
    49.  
    50.         transform.position = start;
    51.  
    52.         transform.eulerAngles = new Vector3(0, 0, Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg);
    53.  
    54.         if (length <= minLength)
    55.         {
    56.             bottomCap.localPosition = minLength * Vector2.right;
    57.  
    58.             center.localScale = new Vector3(1, 0, 1);
    59.  
    60.             transform.localScale = new Vector3(length / minLength, 1, 1);
    61.         }
    62.         else
    63.         {
    64.             bottomCap.localPosition = length * Vector2.right;
    65.  
    66.             length -= minLength;
    67.  
    68.             center.localScale = new Vector3(1, length * invCenterLength, 1);
    69.  
    70.             transform.localScale = new Vector3(1, 1, 1);
    71.         }
    72.     }
    73. }
     
    bsks777 likes this.
  3. raviraj_vdy

    raviraj_vdy

    Joined:
    May 14, 2009
    Posts:
    309
    Thank you very much PGJ it works like a charm :):):):):):):):):):):):):):):):D:D:D:D:D:D:D:D:D:D:D:D:D:D Your setup was easy to understand :D:D
     
  4. raviraj_vdy

    raviraj_vdy

    Joined:
    May 14, 2009
    Posts:
    309
    Hello Guys can we draw a line in a circular way ?
     

    Attached Files:

  5. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Are you only going for complete circles or do you want to be able to do arcs as well?
     
  6. raviraj_vdy

    raviraj_vdy

    Joined:
    May 14, 2009
    Posts:
    309
    Yes circles and arcs both
     
  7. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    So, I did a test of drawing circles using sprites as segments. Just to see if it was possible to go a step further with the techniques I used in the line script. I'm pretty sure that this isn't a good way to go about drawing circles/arcs. But it works surprisingly well :) Since the script constructs the arc segments within a GameObject, once it's created, it is possible to rotate, scale, move and so on without recreating the circle. Also, since it uses a prefab for the segments you can use colliders on the prefab, thereby your game objects can collide with the circle. Which is rather useful.

    To use it, create an empty game object. This will be the container for the arc segments. Assign the script to the object and assign a prefab as "Arc Object". I used the center section that was used with the line solution. That is a square object with the pivot at the top.

    The script is long and far from optimized and probably needs a lot of work...
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DrawCircle : MonoBehaviour
    5. {
    6.     public GameObject arcObject;
    7.     public Vector2 pCenter = Vector2.zero;
    8.     public float pRadius = 4f;
    9.     [Header("Angles")]
    10.     public float pStartAngle = 0f;
    11.     public float pStopAngle = 180f;
    12.     [Space(10)]
    13.     public float pSegments = 8f;
    14.  
    15.     // Test stuff
    16.     Vector2 tCenter = Vector2.zero;
    17.     float tRadius = 0f;
    18.     float tStartAngle = 0f;
    19.     float tStopAngle = 0f;
    20.     float tSegments = 0f;
    21.  
    22.  
    23.     private void Update()
    24.     {
    25.  
    26.         // Testing
    27.         if (Input.GetButton("Fire1"))
    28.         {
    29.             pStopAngle += 1;
    30.         }
    31.  
    32.         if (
    33.             pCenter != tCenter ||
    34.             pRadius != tRadius ||
    35.             pStartAngle != tStartAngle ||
    36.             pStopAngle != tStopAngle ||
    37.             pSegments != tSegments
    38.            )
    39.         {
    40.             EraseCircle();
    41.            
    42.             DrawArc(pCenter, pRadius, pStartAngle, pStopAngle, pSegments);
    43.  
    44.             tCenter = pCenter;
    45.             tRadius = pRadius;
    46.             tStartAngle = pStartAngle;
    47.             tStopAngle = pStopAngle;
    48.             tSegments = pSegments;
    49.         }
    50.     }
    51.  
    52.     void DrawArc(Vector2 midPoint, float radius = 1f, float startAngle = 0f, float stopAngle = 360f, float segments = 8f)
    53.     {
    54.         if (segments <= 0)
    55.         {
    56.             return;
    57.         }
    58.  
    59.         if (stopAngle < startAngle)
    60.         {
    61.             float t = stopAngle;
    62.  
    63.             stopAngle = startAngle;
    64.             startAngle = t;
    65.         }
    66.  
    67.         if (Mathf.Abs(stopAngle - startAngle) > 360)
    68.         {
    69.             stopAngle = startAngle + 360;
    70.         }
    71.  
    72.         float step = (stopAngle - startAngle) / segments;
    73.  
    74.         Vector2 extents = arcObject.GetComponent<Renderer>().bounds.extents;
    75.  
    76.         float scale = 1 / (2 * extents.y);
    77.  
    78.         float cover = Mathf.Sin(step / 2f * Mathf.Deg2Rad) * extents.x;
    79.  
    80.         Vector2 currentPoint = midPoint + radius * new Vector2(Mathf.Cos(startAngle * Mathf.Deg2Rad), Mathf.Sin(startAngle * Mathf.Deg2Rad));
    81.         Vector2 nextPoint = midPoint + radius * new Vector2(Mathf.Cos((startAngle + step) * Mathf.Deg2Rad), Mathf.Sin((startAngle + step) * Mathf.Deg2Rad)); ;
    82.  
    83.         float length = (currentPoint - nextPoint).magnitude;
    84.         Vector3 lScale = arcObject.transform.localScale;
    85.  
    86.         lScale.y *= (length + cover * 2) * scale;
    87.  
    88.         float angle = startAngle;
    89.         for (int i = 0; i < segments; i++)
    90.         {
    91.             nextPoint =
    92.                 midPoint + radius * new Vector2(Mathf.Cos((angle + step) * Mathf.Deg2Rad), Mathf.Sin((angle + step) * Mathf.Deg2Rad));
    93.  
    94.             Vector2 dir = (nextPoint - currentPoint).normalized;
    95.  
    96.             currentPoint = nextPoint;
    97.  
    98.             nextPoint += dir * cover;
    99.  
    100.             GameObject go =
    101.                 Instantiate(
    102.                     arcObject,
    103.                     nextPoint,
    104.                     Quaternion.Euler(0, 0, Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90)
    105.                     ) as GameObject;
    106.  
    107.             go.transform.localScale = lScale;
    108.  
    109.             go.transform.SetParent(transform);
    110.  
    111.             go.name = "Arc " + i;
    112.  
    113.             angle += step;
    114.         }
    115.     }
    116.  
    117.     void EraseCircle()
    118.     {
    119.         foreach (Transform t in transform.GetComponentsInChildren<Transform>())
    120.         {
    121.             if (t != transform)
    122.             {
    123.                 Destroy(t.gameObject);
    124.             }
    125.         }
    126.     }
    127. }
     
    bariscigal likes this.
  8. raviraj_vdy

    raviraj_vdy

    Joined:
    May 14, 2009
    Posts:
    309
    Hello PGJ,

    This is a great solution, It was easy to set-up & its super coool !!! :):):):D:D:D

    Thanks,
    Raviraj