- Home /
How to find the radius area of linerencderer drawn circle and move objects inside ?
This script is attached to a 3d cube. and it's drawing a circle around the cube using linerenderer.
Then I'm using a sphere just for coloring and mark the radius area between the drawn circle and the cube. On this area of the sphere that is also the circle radius area I want to make some objects that will move around the area randomly. inside the radius area.
Because I didn't find a way to fill the drawn circle I used sphere for that.
In the screenshot I want objects to move randomly in the blue area in the sphere area but on the cube to exclude the cube. If I could some how to fill the drawn linerenderer circle with blue without using sphere ? but for now I'm using sphere.
The script
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteAlways]
[RequireComponent(typeof(UnityEngine.LineRenderer))]
public class DrawCircle : MonoBehaviour
{
[Range(1, 50)] public int segments = 50;
[Range(1, 500)] public float xRadius = 5;
[Range(1, 500)] public float yRadius = 5;
[Range(0.1f, 5)] public float width = 0.1f;
[Range(0, 100)] public float height = 0;
public bool controlBothXradiusYradius = false;
public bool draw = true;
[SerializeField] private LayerMask targetLayers;
[SerializeField] private LineRenderer line;
private void Start()
{
if (!line) line = GetComponent<LineRenderer>();
if (draw)
CreatePoints();
}
private void Update()
{
if (Physics.CheckSphere(transform.position, xRadius, targetLayers))
{
Debug.Log("player detected");
}
else
{
Debug.Log("player NOT detected");
}
}
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, height, y);
angle += (360f / 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 float prevHeight;
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 || height != prevHeight)
{
CreatePoints();
// Cache our most recently used values.
prevXRadius = xRadius;
prevYRadius = yRadius;
prevSegments = segments;
prevWidth = width;
prevHeight = height;
}
if (controlBothXradiusYradius)
{
yRadius = xRadius;
}
}
}
#endif
}
Answer by Firnox · Feb 02 at 10:10 PM
I don't fully understand your question for finding the radius, because you the radius of the circle is exactly what you specified the radius of the line renderer to be?
For drawing the circle, you could use a custom mesh renderer to do this for you. I have a YouTube video on this that explains how to make a custom mesh for a regular polygon - and a circle is a just a regular polygon with many vertices. In fact you've already got the coordinates of the circles vertices that you're using to create the line render, so all that's really left is to create the triangles.
I've added in the mesh components to your code that would create a circle for you to fill in the line renderer, all you need to do is add a material to the inspector.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteAlways]
[RequireComponent(typeof(UnityEngine.LineRenderer), typeof(UnityEngine.MeshFilter), typeof(UnityEngine.MeshRenderer))]
public class DrawCircle : MonoBehaviour {
[Range(1, 50)] public int segments = 50;
[Range(1, 500)] public float xRadius = 5;
[Range(1, 500)] public float yRadius = 5;
[Range(0.1f, 5)] public float width = 0.1f;
[Range(0, 100)] public float height = 0;
public bool controlBothXradiusYradius = false;
public bool draw = true;
[SerializeField] private LayerMask targetLayers;
[SerializeField] private LineRenderer line;
// Add required components to display a mesh.
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
private Mesh mesh;
[SerializeField] private Material material;
private void Start() {
if (!line) line = GetComponent<LineRenderer>();
// Get references to the mesh components, and instantiate the mesh.
meshFilter = GetComponent<MeshFilter>();
meshRenderer = GetComponent<MeshRenderer>();
mesh = new Mesh();
meshFilter.mesh = mesh;
if (draw)
CreatePoints();
}
private void Update() {
if (Physics.CheckSphere(transform.position, xRadius, targetLayers)) {
Debug.Log("player detected");
} else {
Debug.Log("player NOT detected");
}
}
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, height, y);
angle += (360f / segments);
}
// it's way more efficient to do this in one go!
line.SetPositions(points);
// Clear the mesh points so we can redraw it.
mesh.Clear();
meshRenderer.material = material;
// Use the same points as the line renderer.
mesh.vertices = points;
// The triangle vertices must be done in clockwise order.
int[] triangles = new int[3 * (segments - 2)];
for (int i = 0; i < segments - 2; i++) {
triangles[3 * i] = 0;
triangles[(3 * i) + 1] = i + 1;
triangles[(3 * i) + 2] = i + 2;
}
mesh.triangles = triangles;
}
#if UNITY_EDITOR
private float prevXRadius, prevYRadius;
private int prevSegments;
private float prevWidth;
private float prevHeight;
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 || height != prevHeight) {
CreatePoints();
// Cache our most recently used values.
prevXRadius = xRadius;
prevYRadius = yRadius;
prevSegments = segments;
prevWidth = width;
prevHeight = height;
}
if (controlBothXradiusYradius) {
yRadius = xRadius;
}
}
}
#endif
}
Your answer
Follow this Question
Related Questions
Rotate around a circle 0 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Draw shortest distance between 2 points on a sphere 1 Answer
Setting Line Render position directly forward from facing of game object 1 Answer