- Home /
How can I animate linerenderer lines over time ?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Tilemaps;
using UnityEngine.WSA;
public class ShowMeshBounds : MonoBehaviour
{
public Color color = Color.green;
public int lineDrawSpeed = 3;
public bool animatedLines = false;
private Vector3 v3FrontTopLeft;
private Vector3 v3FrontTopRight;
private Vector3 v3FrontBottomLeft;
private Vector3 v3FrontBottomRight;
private Vector3 v3BackTopLeft;
private Vector3 v3BackTopRight;
private Vector3 v3BackBottomLeft;
private Vector3 v3BackBottomRight;
private float distance;
private float counter = 0;
private void Start()
{
CalcPositons();
DrawBox();
}
private void Update()
{
AnimateLines();
}
void CalcPositons()
{
Bounds bounds = GetComponent<MeshFilter>().sharedMesh.bounds;
Vector3 v3Center = bounds.center;
Vector3 v3Extents = bounds.extents;
v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top left corner
v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top right corner
v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom left corner
v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom right corner
v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top left corner
v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top right corner
v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom left corner
v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom right corner
v3FrontTopLeft = transform.TransformPoint(v3FrontTopLeft);
v3FrontTopRight = transform.TransformPoint(v3FrontTopRight);
v3FrontBottomLeft = transform.TransformPoint(v3FrontBottomLeft);
v3FrontBottomRight = transform.TransformPoint(v3FrontBottomRight);
v3BackTopLeft = transform.TransformPoint(v3BackTopLeft);
v3BackTopRight = transform.TransformPoint(v3BackTopRight);
v3BackBottomLeft = transform.TransformPoint(v3BackBottomLeft);
v3BackBottomRight = transform.TransformPoint(v3BackBottomRight);
}
void DrawBox()
{
SpawnLineGenerator(v3FrontTopLeft, v3FrontTopRight, color);
SpawnLineGenerator(v3FrontTopRight, v3FrontBottomRight, color);
SpawnLineGenerator(v3FrontBottomRight, v3FrontBottomLeft, color);
SpawnLineGenerator(v3FrontBottomLeft, v3FrontTopLeft, color);
SpawnLineGenerator(v3BackTopLeft, v3BackTopRight, color);
SpawnLineGenerator(v3BackTopRight, v3BackBottomRight, color);
SpawnLineGenerator(v3BackBottomRight, v3BackBottomLeft, color);
SpawnLineGenerator(v3BackBottomLeft, v3BackTopLeft, color);
SpawnLineGenerator(v3FrontTopLeft, v3BackTopLeft, color);
SpawnLineGenerator(v3FrontTopRight, v3BackTopRight, color);
SpawnLineGenerator(v3FrontBottomRight, v3BackBottomRight, color);
SpawnLineGenerator(v3FrontBottomLeft, v3BackBottomLeft, color);
}
void SpawnLineGenerator(Vector3 start, Vector3 end, Color color)
{
GameObject myLine = new GameObject();
myLine.tag = "FrameLine";
myLine.name = "FrameLine";
myLine.AddComponent<LineRenderer>();
LineRenderer lr = myLine.GetComponent<LineRenderer>();
lr.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));
lr.startColor = color;
lr.useWorldSpace = false;
lr.endColor = color;
lr.startWidth = 0.03f;
lr.endWidth = 0.03f;
lr.SetPosition(0, start);
distance = Vector3.Distance(start, end);
AnimateLines();
}
private void AnimateLines()
{
if(counter < distance)
{
counter += .1f / lineDrawSpeed;
float x = Mathf.Lerp(0, distance, counter);
Vector3 pointalongLine = x * Vector3.Normalize(end - start) + start;
lr.SetPosition(1, end);
}
}
}
I have in this case 12 lines I want them start together at specific speed to start moving from start to end. I created the AnimateLines method and I want using the lineDrawSpeed and the animatedLines bool and the distance and counter and start and end of each line to make the lines start drawing.
But I messed up the AnimateLines and not sure how to use it to get the end and start and then call it in the Update.
Okay, I can write it as a code for you, but hear me out, since you are using linerenderer to create all the lines, first create a prefab of linerenderer.
To the prefab attach a script, that holds a vector3 called finalPositionOfEnd.
In the start function, SpawnLineGenerator function, set end value = start value of linerenderer, but ins$$anonymous$$d of creating one, you instantiate prefab. Now you store the correct end value in the script attached to the linerenderer prefab.
Now, in the update function, if bool animatedLines is true, you run function where you lerp the end position of linerender from current position to the vector3 stored in the script attached to the script. That way you can get animated lines.
Let me know if this worked, feel free to ask any questions.
I'm a bit confused sorry.
What I did is adding new empty GameObject in the editor then named it to AnimateLines then attached script to it with the variable
public Vector3 finalPositionOfEnd;
Then attached to it a LineRenderer component.
Then dragged the empty gameobject to the Project > Assets and now I have a prefab. Next I copied the method SpawnLineGenerator from my other script to the new one.
Now I don't understand how to set the end value to the linerenderer start value ? And since I'm using linerenderer prefab then I don't need this line :
GameObject myLine = new GameObject();
Just using transform ins$$anonymous$$d ?
I think I messed it all up. $$anonymous$$aybe you can show me a bit the start or part of the code how it should be ? Sorry.
You are almost there, you use instantiate(LineRendererPrefab)
ins$$anonymous$$d of GameObject myLine = new GameObject();
in your code, you are using lr.SetPosition(0, start);
now you add
lr.SetPosition(1, start);
this will create linerenderers with end position as start position.
after this code, store all the prefabs you've created in an array. you can do this by adding a tag to the the prefab. Say you assign a tag Lines in the inspector when creating the prefab before dragging into assets.
AllLines = GameObject.FindGameObjectsWithTag("Lines");
This would return an array gameobjects.
Now, within the update() loop, you do
foreach (GameObject thisLine in AllLines)
{
thisLRenderer = thisLine.GetComponent<LineRenderer>();
// now slowly lerp from the start to end point.
}
to see how to lerp from start to end point, you will need to add some code in the start function like this link.
I dont know if this is the best method, but I am just using ideas on top of my $$anonymous$$d. Let me know if you solve it, if not I will try it in unity and send you the full code if I can.
Answer by cooldude5757 · Feb 08, 2018 at 01:16 AM
Okay, so finally I got time to do it and here is what I got.
If this is what you are looking for, create a tag called FrameLine and create two scripts, namely ShowMeshBounds.cs and EndHolder.cs
EndHolder.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EndHolder : MonoBehaviour {
public Vector3 EndVector;
}
ShowMeshBounds.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Tilemaps;
using UnityEngine.WSA;
public class ShowMeshBounds : MonoBehaviour
{
public Color color = Color.green;
private Vector3 v3FrontTopLeft;
private Vector3 v3FrontTopRight;
private Vector3 v3FrontBottomLeft;
private Vector3 v3FrontBottomRight;
private Vector3 v3BackTopLeft;
private Vector3 v3BackTopRight;
private Vector3 v3BackBottomLeft;
private Vector3 v3BackBottomRight;
public bool animateLines;
public float speed = 1f;
GameObject[] allLines;
private void Start()
{
CalcPositons();
DrawBox();
allLines = GameObject.FindGameObjectsWithTag("FrameLine");
}
void CalcPositons()
{
Bounds bounds = GetComponent<MeshFilter>().sharedMesh.bounds;
Vector3 v3Center = bounds.center;
Vector3 v3Extents = bounds.extents;
v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top left corner
v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top right corner
v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom left corner
v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom right corner
v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top left corner
v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top right corner
v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom left corner
v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom right corner
v3FrontTopLeft = transform.TransformPoint(v3FrontTopLeft);
v3FrontTopRight = transform.TransformPoint(v3FrontTopRight);
v3FrontBottomLeft = transform.TransformPoint(v3FrontBottomLeft);
v3FrontBottomRight = transform.TransformPoint(v3FrontBottomRight);
v3BackTopLeft = transform.TransformPoint(v3BackTopLeft);
v3BackTopRight = transform.TransformPoint(v3BackTopRight);
v3BackBottomLeft = transform.TransformPoint(v3BackBottomLeft);
v3BackBottomRight = transform.TransformPoint(v3BackBottomRight);
}
void DrawBox()
{
SpawnLineGenerator(v3FrontTopLeft, v3FrontTopRight, color);
SpawnLineGenerator(v3FrontTopRight, v3FrontBottomRight, color);
SpawnLineGenerator(v3FrontBottomRight, v3FrontBottomLeft, color);
SpawnLineGenerator(v3FrontBottomLeft, v3FrontTopLeft, color);
SpawnLineGenerator(v3BackTopLeft, v3BackTopRight, color);
SpawnLineGenerator(v3BackTopRight, v3BackBottomRight, color);
SpawnLineGenerator(v3BackBottomRight, v3BackBottomLeft, color);
SpawnLineGenerator(v3BackBottomLeft, v3BackTopLeft, color);
SpawnLineGenerator(v3FrontTopLeft, v3BackTopLeft, color);
SpawnLineGenerator(v3FrontTopRight, v3BackTopRight, color);
SpawnLineGenerator(v3FrontBottomRight, v3BackBottomRight, color);
SpawnLineGenerator(v3FrontBottomLeft, v3BackBottomLeft, color);
}
void SpawnLineGenerator(Vector3 start, Vector3 end, Color color)
{
GameObject myLine = new GameObject();
myLine.tag = "FrameLine";
myLine.name = "FrameLine";
myLine.AddComponent<LineRenderer>();
myLine.AddComponent<EndHolder>();
myLine.GetComponent<EndHolder>().EndVector = end;
LineRenderer lr = myLine.GetComponent<LineRenderer>();
lr.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));
lr.startColor = color;
lr.useWorldSpace = false;
lr.endColor = color;
lr.startWidth = 0.03f;
lr.endWidth = 0.03f;
lr.SetPosition(0, start);
lr.SetPosition(1, start);
}
void Update()
{
if (animateLines) {
speed++;
foreach (GameObject thisline in allLines)
{
Vector3 endPos = thisline.GetComponent<EndHolder>().EndVector;
Vector3 startPos = thisline.GetComponent<LineRenderer>().GetPosition(0);
Vector3 tempPos = Vector3.Lerp(startPos, endPos, speed/5*Time.deltaTime);
thisline.GetComponent<LineRenderer>().SetPosition(1, tempPos);
}
}
else
{
speed = 0;
foreach (GameObject thisline in allLines)
{
thisline.GetComponent<LineRenderer>().SetPosition(1, thisline.GetComponent<LineRenderer>().GetPosition(0));
}
}
}
}
Let me know if that helped you. Cheers!
This is what I wanted but it have two problems.
When enabled true Animate Lines and running the game it's animating the lines but for some reason the animation of the lines is not smooth. Thel ines start moving then stop for millisecond then continue and then again each few milliseconds or so the lines like stop or pause for a millisecond or so.
When the Animate Lines is not checked enabled false then there are 12 FrameLines objects but there are no lines at all. When Animate Lines is unchecked enabled false it should show the lines too but not animated.
Here is a link for a short video clip I recorded now showing the two problems:
I think I also see the problem my problem number 1 also in your link of imgur you can see in you clip it happens too at least once when the lines animated.
I did a test now in the Update with one single line same problem. The line while is animated it's blinking in some parts and stuttering not moving/growing smooth.
Just replace Line no. 105 with
Vector3 tempPos = Vector3.Lerp(startPos, endPos, speed/200f);
Working great. Last question please and then I mark to accept the question.
The speed variable it's not matter if I will set it's value in the inspector to 0 or 1 or 3 since it's doing speed++ so the speed will always change.
How can I make that changing the speed value in the inspector really will effect the speed in the code ?