简体   繁体   English

如何围绕特定的 object 和/或围绕鼠标单击 position 画一个圆圈?

[英]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.这将围绕脚本附加到的 object 创建一个圆圈。

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.但是我想稍微改变一下脚本并添加一个目标变量,如果目标不是 null,即使脚本没有附加到这个目标,也要围绕目标转一圈。 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.也许使用一个标志来决定是围绕目标还是围绕 object 创建圆,就像现在一样。

I added at the top a target variable:我在顶部添加了一个目标变量:

public Transform target;

Then changed both x and y lines:然后更改了 x 和 y 行:

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.我正在尝试做的另一件事是添加鼠标按下单击事件,当鼠标按住并拖动时,它将在单击的鼠标 position 周围创建圆圈,并在按住鼠标并拖动鼠标的同时更改圆半径.

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.为了在目标周围绘制圆圈,我尝试在 Start() 中向目标 object 添加 LineRenderer 组件,但它没有改变任何东西。

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...?一个普遍的问题:为什么你的圆有380度而不是360度......?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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