Reputation: 2001
Following this tutorial, I'm trying to use Line Renderer component to draw a sine wave from point A to B.I'm using the input mouse position. However what I did so far is not working, it just draw the sine wave along the x axis, I need to draw it from the start point to the input mouse position.
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);
}
Upvotes: 0
Views: 2644
Reputation: 90714
As an alternative I would suggest to instead use
lineRenderer.useWorlsSpace = false;
so the points are no longer set in worldspace but in the local space relative to the linerenderer transform.
Now you can simply rotate the linerenderer transform to point towards the latest user input position.
I couldn't use your code example since I don't know what your prefabs are and do so I created my own from the code in the given Video. I hope you can reuse/recreate the parts necessary
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);
}
}
Btw I just assume here that GameObject.FindGameObjectsWithTag("PointMarker");
actually retuns all the so far spawned linePointPrefab
objects.
It would be better to store them right away when you spawn them like
private List<Transform> allPoints = new List<Transform>();
...
allPoints.Add(Instantiate(linePointPrefab, pointPosition, Quaternion.identity).transform);
then you can skip the usage of FindObjectsWithType
completely
For adopting this local space position also for the line point prefabs you instantiate simply instantiate them as child of the linerenderer transform or spawn them and the linerenderer under the same parent so the relative positions are the same. In this case you wouldn't rotate the linerenderer but the entire parent object so the spawned linepoints are rotated along with it
Upvotes: 2