如何围绕特定对象和/或鼠标单击位置绘制圆


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

这会在脚本所附的对象周围创建一个圆圈。

但我想稍微修改一下脚本,添加一个目标变量,如果目标不为null,即使脚本没有附加到这个目标上,也要在目标周围绕一圈。也许可以使用一个标志来决定是围绕目标还是围绕脚本所附着的对象创建圆圈,就像现在一样。

我在顶部添加了一个目标变量:

public Transform target;

然后更改了x和y行:

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

但它并不是围绕目标绘制,当我将变换指定给目标时,它只是围绕脚本所附着的变换创建一个圆圈,而不是围绕目标。

我正在尝试做的另一件事是添加一个鼠标向下点击事件,当鼠标被按住并拖动时,它将在单击的鼠标位置周围创建一个圆圈,并在按住鼠标并拖动鼠标的同时更改圆圈半径。

但首先如何画出围绕目标的圆圈?

为了围绕目标绘制圆,我试图在Start((中向目标对象添加LineRenderer组件,但它没有改变任何内容。

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

您正在设置

line.useWorldSpace = false;

这意味着你提供的位置必须相对于这个对象变换。

无论如何,这似乎不是你想要的,所以简单地删除该行,或者将其设置为

line.useWorldSpace = true;

或者,如果你真的想保留局部空间的功能,也就是说,如果你移动这个变换,那么线就会随之移动——我对此表示怀疑,但只是为了完整性——你可以使用

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

一个普遍的问题:为什么你的圆有380度而没有360度。。。?

最新更新