How can I draw a circle using linerenderer and make it the circle as object child of the object is should draw around?

Viewed 703

When I attach this script to an object it will draw a circle around it. Now I want to make that the script the linerenderer will be attached to empty gameobject that will be a child of the object that it will draw the circle around.

I want that so I can drag the empty gameobject and change the circle height. That way I can simple duplicate the empty gameobject and have two circles one on ground on higher. and both circle will be the same radius around the parent object the parent object will be the center.

using UnityEngine;
using System.Collections;
using System;

[ExecuteAlways]
[RequireComponent(typeof(LineRenderer))]
public class DrawRadiusAroundTurret : MonoBehaviour
{
    [Range(1, 50)] public int segments = 50;
    [Range(1, 5)] public float xRadius = 5;
    [Range(1, 5)] public float yRadius = 5;
    [Range(0.1f, 5f)] public float width = 0.1f;
    public bool controlBothXradiusYradius = false;
    public bool draw = true;

    [SerializeField] private LineRenderer line;

    private void Start()
    {
        if (!line) line = GetComponent<LineRenderer>();

        CreatePoints();
    }

    public void CreatePoints()
    {
        line.enabled = true;
        line.widthMultiplier = width;
        line.useWorldSpace = false;
        line.widthMultiplier = width;
        line.positionCount = segments + 1;

        float x;
        float y;

        var angle = 20f;
        var points = new Vector3[segments + 1];
        for (int i = 0; i < segments + 1; i++)
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xRadius;
            y = Mathf.Cos(Mathf.Deg2Rad * angle) * yRadius;

            points[i] = new Vector3(x, 0f, y);

            angle += (380f / segments);
        }

        // it's way more efficient to do this in one go!
        line.SetPositions(points);
    }

#if UNITY_EDITOR
    private float prevXRadius, prevYRadius;
    private int prevSegments;
    private float prevWidth;

    private void OnValidate()
    {
        // Can't set up our line if the user hasn't connected it yet.
        if (!line) line = GetComponent<LineRenderer>();
        if (!line) return;

        if (!draw)
        {
            // instead simply disable the component
            line.enabled = false;
        }
        else
        {
            // Otherwise re-enable the component
            // This will simply re-use the previously created points
            line.enabled = true;

            if (xRadius != prevXRadius || yRadius != prevYRadius || segments != prevSegments || width != prevWidth)
            {
                CreatePoints();

                // Cache our most recently used values.
                prevXRadius = xRadius;
                prevYRadius = yRadius;
                prevSegments = segments;
                prevWidth = width;
            }

            if (controlBothXradiusYradius)
            {
                yRadius = xRadius;
            }
        }
    }
#endif
}

The linerenderer and the script are both attached to the Missles Turrent instead I want them to be on empty gameobject child of the Missles Turrent and that it will keep drawing the same circle around the Missles Turrent but when it will be from the child object I will be able to change the circle height.

The main goal is to have multiple circles around the Missles Turrent but that I will be able to change the circles height with a simple drag.

1 Answers

The solution is to create empty gameobject/s as children each child position set to 0,0,0 Then adding to each child a linerenderer component and the script.

The script :

using UnityEngine;
using System.Collections;
using System;

[ExecuteAlways]
[RequireComponent(typeof(LineRenderer))]
public class DrawRadiusAroundTurret : MonoBehaviour
{
    [Range(1, 50)] public int segments = 50;
    [Range(1, 5)] public float xRadius = 5;
    [Range(1, 5)] public float yRadius = 5;
    [Range(0.1f, 5f)] public float width = 0.1f;
    public bool controlBothXradiusYradius = false;
    public bool draw = true;

    [SerializeField] private LineRenderer line;

    private void Start()
    {
        if (!line) line = GetComponent<LineRenderer>();

        CreatePoints();
    }

    //private void Update()
    //{
    //    
    //}

    public void CreatePoints()
    {
        line.enabled = true;
        line.widthMultiplier = width;
        line.useWorldSpace = false;
        line.widthMultiplier = width;
        line.positionCount = segments + 1;

        float x;
        float y;

        var angle = 20f;
        var points = new Vector3[segments + 1];
        for (int i = 0; i < segments + 1; i++)
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xRadius;
            y = Mathf.Cos(Mathf.Deg2Rad * angle) * yRadius;

            points[i] = new Vector3(x, 0f, y);

            angle += (380f / segments);
        }

        // it's way more efficient to do this in one go!
        line.SetPositions(points);
    }

#if UNITY_EDITOR
    private float prevXRadius, prevYRadius;
    private int prevSegments;
    private float prevWidth;

    private void OnValidate()
    {
        // Can't set up our line if the user hasn't connected it yet.
        if (!line) line = GetComponent<LineRenderer>();
        if (!line) return;

        if (!draw)
        {
            // instead simply disable the component
            line.enabled = false;
        }
        else
        {
            // Otherwise re-enable the component
            // This will simply re-use the previously created points
            line.enabled = true;

            if (xRadius != prevXRadius || yRadius != prevYRadius || segments != prevSegments || width != prevWidth)
            {
                CreatePoints();

                // Cache our most recently used values.
                prevXRadius = xRadius;
                prevYRadius = yRadius;
                prevSegments = segments;
                prevWidth = width;
            }

            if (controlBothXradiusYradius)
            {
                yRadius = xRadius;
            }
        }
    }
#endif
}

Screenshot :

Circles

Related