'Which drawn circle radius is correct?

This script is attached to a sphere and drawing a pink circle around the sphere using a linerenderer. Then i can set the circle radius in the editor or at runtime. in this screenshot the radius is 1.

circle around sphere

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 += (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 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;

                CreatePoints();
            }
        }
    }
#endif
}

This script is attached to a cube making the cube moving around the sphere with a given radius :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateAroundTarget : MonoBehaviour
{
    // Drag & drop the player in the inspector
    public Transform target;
    public float distance;
    public DrawCircle dc;
    public float dcDistance;
    public float CircleRadius = 1;

    public float RotationSpeed = 1;

    public float ElevationOffset = 0;

    [Range(0, 360)]
    public float StartAngle = 0;

    public bool UseTargetCoordinateSystem = false;

    public bool LookAtTarget = false;

    private float angle;

    private Vector3 radiusPosition;

    private void Awake()
    {
        angle = StartAngle;
    }

    private void LateUpdate()
    {
        distance = Vector3.Distance(transform.position, target.position);

        if(dc != null)
        {
            radiusPosition = new Vector3(target.position.x,
                    target.position.y, target.position.z + dc.xRadius);

            dcDistance = Vector3.Distance(transform.position, radiusPosition);
        }

        // Define the position the object must rotate around
        Vector3 position = target != null ? target.position : Vector3.zero;

        Vector3 positionOffset = ComputePositionOffset(angle);

        // Assign new position
        transform.position = position + positionOffset;

        // Rotate object so as to look at the target
        if (LookAtTarget)
            transform.rotation = Quaternion.LookRotation(position - transform.position, target == null ? Vector3.up : target.up);

        angle += Time.deltaTime * RotationSpeed;
    }

    private Vector3 ComputePositionOffset(float a)
    {
        a *= Mathf.Deg2Rad;

        // Compute the position of the object
        Vector3 positionOffset = new Vector3(
            Mathf.Cos(a) * CircleRadius,
            ElevationOffset,
            Mathf.Sin(a) * CircleRadius
        );

        // Change position if the object must rotate in the coordinate system of the target
        // (i.e in the local space of the target)
        if (target != null && UseTargetCoordinateSystem)
            positionOffset = target.TransformVector(positionOffset);

        return positionOffset;
    }

#if UNITY_EDITOR

    [SerializeField]
    private bool drawGizmos = true;

    private void OnDrawGizmosSelected()
    {
        if (!drawGizmos)
            return;

        // Draw an arc around the target
        Vector3 position = target != null ? target.position : Vector3.zero;
        Vector3 normal = Vector3.up;
        Vector3 forward = Vector3.forward;
        Vector3 labelPosition;

        Vector3 positionOffset = ComputePositionOffset(StartAngle);
        Vector3 verticalOffset;


        if (target != null && UseTargetCoordinateSystem)
        {
            normal = target.up;
            forward = target.forward;
        }
        verticalOffset = positionOffset.y * normal;

        // Draw label to indicate elevation
        if (Mathf.Abs(positionOffset.y) > 0.1)
        {
            UnityEditor.Handles.DrawDottedLine(position, position + verticalOffset, 5);
            labelPosition = position + verticalOffset * 0.5f;
            labelPosition += Vector3.Cross(verticalOffset.normalized, target != null && UseTargetCoordinateSystem ? target.forward : Vector3.forward) * 0.25f;
            UnityEditor.Handles.Label(labelPosition, ElevationOffset.ToString("0.00"));
        }

        position += verticalOffset;
        positionOffset -= verticalOffset;

        UnityEditor.Handles.DrawWireArc(position, normal, forward, 360, CircleRadius);

        // Draw label to indicate radius
        UnityEditor.Handles.DrawLine(position, position + positionOffset);
        labelPosition = position + positionOffset * 0.5f;
        labelPosition += Vector3.Cross(positionOffset.normalized, target != null && UseTargetCoordinateSystem ? target.up : Vector3.up) * 0.25f;
        UnityEditor.Handles.Label(labelPosition, CircleRadius.ToString("0.00"));
    }

#endif
}

I'm using gizmos and Handles to draw a circle in white. This white circle represent the radius value of the radius variable.

I have two variables i'm using for debugging in the inspector to see the current radius in runtime.

The first variable is distance the second variable is dcDistance. dcDistance get the radius i set in the first script the DrawCircle.

In this case both radius and xRadius set to 1. the problem is that the cube rotate on the white thin line of the radius but the pink circle radius seems not accurate.

The pink circle is smaller then the white thin circle even of both set to the same radius. Why the linerenderer circle is smaller if the radius is set to 1 ? it should be the same size of the thin white circle or am i wrong ?

In the second screenshot you can see that dcDistance value is 0.3214808 and while the cube is moving on the circle the value of dcDistance change a lot between 0.3 to 0.4 to 0.9 while the distance value of the radius variable is change between 0.99999 and 1 so i know that the working accurate radius is the white circle in the second script and the not accurate radius is in the DrawCircle script.

thin white circle

The main goal is to make the cube to move on the pink circle depending on the radius in DrawCircle script. but it seems that the DrawCircle radius is not accurate or something else not accurate.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source