在this tutorial之后,我试图使用Line Renderer组件从A点到B点绘制一个正弦波。我正在使用输入的鼠标位置。但是到目前为止,我所做的工作没有用,它只是沿x轴绘制正弦波,我需要将其从起点绘制到输入鼠标的位置。
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 newPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
newPos.z = 0;
CreatePointMarker(newPos);
GenerateNewLine();
}
}
private void CreatePointMarker(Vector3 pointPosition)
{
Instantiate(linePointPrefab, pointPosition, Quaternion.identity);
}
private void GenerateNewLine()
{
GameObject[] allPoints = GameObject.FindGameObjectsWithTag("PointMarker");
Vector3[] allPointPositions = new Vector3[allPoints.Length];
var pointList = new List<Vector3>();
for (int i = 0; i < 50; i ++)
{
var dir = allPoints[0].transform.position - allPoints[1].transform.position;
float x = dir.x * i;
float y = Mathf.Sin(x * Time.time);
var sine = new Vector3(x, y, 0f);
var tangentLine = allPoints[0].transform.position + sine;
pointList.Add(tangentLine);
}
SpawnLineGenerator(pointList.ToArray());
}
}
private void SpawnLineGenerator(Vector3[] linePoints)
{
GameObject newLineGen = Instantiate(lineGeneratorPrefab);
LineRenderer lRend = newLineGen.GetComponent<LineRenderer>();
lRend.positionCount = linePoints.Length;
lRend.SetPositions(linePoints);
}
答案 0 :(得分:2)
作为替代方案,我建议改为使用
lineRenderer.useWorlsSpace = false;
因此,相对于线性渲染器变换,不再在世界空间中设置点,而是在局部空间中设置点。
现在,您只需旋转线性渲染器变换以指向最新的用户输入位置即可。
我无法使用您的代码示例,因为我不知道您的预制件是什么,因此我根据给定Video中的代码创建了自己的预制件。我希望您可以重复使用/重新创建必要的部分
public class SinusWave : MonoBehaviour
{
public Vector3 initalPosition;
public int pointCount = 10;
public LineRenderer line;
private Vector3 secondPosition;
private Vector3[] points;
private float segmentWidth;
private void Awake()
{
line = GetComponent<LineRenderer>();
line.positionCount = pointCount;
// tell the linerenderer to use the local
// transform space for the point coorindates
line.useWorldSpace = false;
points = new Vector3[pointCount];
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
// Camera.main.ScreenToWorldPoint needs a value in Z
// for the distance to camera
secondPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition - Vector3.forward * Camera.main.transform.position.z);
secondPosition.z = 0;
var dir = secondPosition - initalPosition;
// get the segmentWidth from distance to end position
segmentWidth = Vector3.Distance(initalPosition, secondPosition) / pointCount;
// get the difference angle in the Z axis between the current transform.right
// and the direction
var angleDifference = Vector3.SignedAngle(transform.right, dir, Vector3.forward);
// and rotate the linerenderer transform by that angle in the Z axis
// so the result will be that it's transform.right
// points now towards the clicked position
transform.Rotate(Vector3.forward * angleDifference, Space.World);
}
for (var i = 0; i < points.Length; ++i)
{
float x = segmentWidth * i;
float y = Mathf.Sin(x * Time.time);
points[i] = new Vector3(x, y, 0);
}
line.SetPositions(points);
}
}
顺便说一句,我只是在这里假设GameObject.FindGameObjectsWithTag("PointMarker");
实际上重新调整了所有迄今为止产生的linePointPrefab
对象。
最好在生成它们时立即存储它们
private List<Transform> allPoints = new List<Transform>();
...
allPoints.Add(Instantiate(linePointPrefab, pointPosition, Quaternion.identity).transform);
然后您可以完全跳过FindObjectsWithType
的使用
要在线点预制件上也采用此局部空间位置,只需实例化它们即可作为线性渲染器转换的子对象实例化,或将它们与线性渲染器生成在同一父对象下,以便相对位置相同。在这种情况下,您将不会旋转线性渲染器,而是旋转整个父对象,因此生成的线点会随之旋转