- Home /
How can calculate the drawn circle range ?
In this script i draw a circle around a gameobject:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(LineRenderer))]
public class DrawCircle : MonoBehaviour
{
[Range(0, 50)]
public int segments = 50;
[Range(0, 5)]
public float xradius = 5;
[Range(0, 5)]
public float yradius = 5;
LineRenderer line;
void Start()
{
line = gameObject.GetComponent<LineRenderer>();
line.positionCount = segments + 1;
line.useWorldSpace = false;
CreatePoints();
}
void Update()
{
CreatePoints();
}
void CreatePoints()
{
float x;
float y;
float z;
float angle = 20f;
for (int i = 0; i < (segments + 1); i++)
{
x = Mathf.Sin(Mathf.Deg2Rad * angle) * xradius;
z = Mathf.Cos(Mathf.Deg2Rad * angle) * yradius;
line.SetPosition(i, new Vector3(x, 0, z));
angle += (360f / segments + 1);
}
}
}
And in this script i want to check when the circle is inside the turret range then rotate the turret:
using UnityEngine;
using System.Collections;
public class Turret : MonoBehaviour
{
public GameObject target;
public float smooth = 1f;
public float rangeSqr;
private void Start()
{
GameObject Enemy = GameObject.Find("Enemy");
DrawCircle drawcircle = Enemy.GetComponent<DrawCircle>();
rangeSqr = drawcircle.xradius * 2;
}
private void Update()
{
float distanceSqr = (transform.position - target.transform.position).sqrMagnitude;
if (distanceSqr < rangeSqr)
{
transform.LookAt(target.transform.position);
}
}
}
But it's not. It's rotating the turret when the object with the circle is very close to the turret much after the circle already passed the range.
I want when the gameobject circle radius is in the range of the turret then rotate the turret.
Answer by Bunny83 · Aug 06, 2017 at 03:15 AM
Here'
rangeSqr = drawcircle.xradius * 2;
you don't calculate the square of the radius but you multiply it by 2. So a radius of 5 would yield a value of 10 (5*2) instead of 25 (5*5).
Why exactly are you using two different radii for x and z ? If the two are not the same the result would be an ellipse instead of a circle. Many logical deductions won't work with an ellipse that does work with circles.
So you should do:
rangeSqr = drawcircle.xradius * drawcircle.xradius;
Note that you only check the center of the object. So the object is only inside when it's pivot enters the range. If the object is large the actual mesh might already overlap with your range but as long as the center isn't inside the range the object will still be considered outside. A common solution is to give both a circular range. You can simply add the two radii before you square it. This way your condition is only true if the two circles overlap.
ps:
If you want to be able to use an ellipse it gets more complicated as the radius depends on the orientation of the object. If your line renderer uses localspace positions the distance vector need to be transformed into the localspace of your linerenderer. The direction vector would be normalized and each component would be multiplied by the corresponding radius. Then you can calculate the squared length / magnitude of that vector. If both objects may use an ellipse each has to use it's own localspace to get the proper radius vector. Again you can simply add the two radius vectors before you get the square length in order to add their radii.
So here's an example for a localspace ellipse:
Vector3 dir = transform.position - target.transform.position;
Vector3 localDir = target.transform.InverseTransformDirection(dir);
localDir = localDir.normalized;
Vector3 localRadius = Vector3.Scale(localDir, new Vector3(drawcircle.xradius, 0, drawcircle.yradius));
Vector3 worldRadius = target.transform.TransformDirection(localRadius);
if (dir.sqr$$anonymous$$agnitude < worldRadius.sqr$$anonymous$$agnitude)
// ...
Note: if you use a worldspace linerenderer (or a localspace renderer that isn't rotated) you can remove the InverseTransformDirection and the TransformDirection
Vector3 dir = transform.position - target.transform.position;
Vector3 worldRadius = Vector3.Scale(dir.normalized, new Vector3(drawcircle.xradius, 0, drawcircle.yradius));
if (dir.sqr$$anonymous$$agnitude < worldRadius.sqr$$anonymous$$agnitude)
// ...
Thank you.
So i did:
rangeSqr = drawcircle.xradius * drawcircle.xradius;
But still the condition is wrong yet. So what the condition should be like now ?
(I changed it all the DrawCircle script is now only on the Turret so there is a drawn circle around the Turret. Should i add the DrawCircle script also to the Enemy GameObject that move to the Turret ?)
And then how do i check if both circles overlap ?
And last thing what should i change in the DrawCircle script , You asked why i'm using different radii for x and z. I don't want to use ellipses only circles. So what should i change in the DrawCircle script ? line.SetPosition(i, new Vector3(x, 0, z)); Should i use only x not z ?
Your answer
Follow this Question
Related Questions
Why when creating new animator controller for the character the character is not walking right ? 0 Answers
How can i Instantiate on the terrain from left to right ? 0 Answers
Why the tile map scripts take almost all the cpu usage ? cpu usage is getting to 99% at times 1 Answer
How can i rotate object by pressing on key R and keep object facing to me my self ? 0 Answers
How can i spawn new gameobjects to be inside the terrain area ? 2 Answers