简体   繁体   中英

How to draw a circle around specific object and/or around the mouse click position?

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 create a circle around the object the script is attached to.

But I want to change the script a bit and to add a target variable and if the target is not null make a circle around the target even if the script is not attached to this target. Maybe using a flag that will decide if to create the circle around the target or around the object the script is attached to like now.

I added at the top a target variable:

public Transform target;

Then changed both x and y lines:

x = target.position.x + Mathf.Cos(Mathf.Deg2Rad * angle) * xRadius;
y = target.position.y + Mathf.Sin(Mathf.Deg2Rad * angle) * yRadius;

But it's not drawing around the target, when I assign a transform to target it's just creating the circle around the transform the script is attached to and not around the target.

Another thing I'm trying to do is to add a mouse down click event and when the mouse is hold down and dragged it will create the circle around the clicked mouse position and will change the circle radius while holding the mouse down and dragging the mouse.

But first how to draw the circle around the target?

For drawing around the target the circle I tried to add a LineRenderer component to the target object in the Start() but it didn't change anything.

if(target.GetComponent<LineRenderer>() == null)
        {
            target.gameObject.AddComponent<LineRenderer>();
        }

You are setting

line.useWorldSpace = false;

which means the positions you provide have to be relative to this objects transform.

Anyway this is not what you want seemingly so simply remove that line or rather set it to

line.useWorldSpace = true;

or if you actually want to keep the functionality of local space, meaning if you move this transform then the line will be moved along with it - which I doubt but just for completeness - you could use

points[i] = transform.InverseTransformPoint( new Vector3(x, height, y));

A general question: Why does your circle have 380 and not 360 degrees...?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM