Line render after 1.2?

Hi all,

I need to use some form of line rendering for my project, either by drawing into a texture, building a mesh-based line (like the Tron-trail demo)…or using the line renderer class.

However, I fail to find enough info on how to use it. The only info on the forums is for use <1.2 and states that the interface changed with version 1.2. Apparently the change was explained somewhere, but I fail to find it.

Anyway, what I don’t get is how to add new lines to an empty object. The functions in the class seem to only set data in existing lines in the array of the line render component - but how do you add the lines in the first place?

Sorry for the ignorance, any pointers would be very welcome!

Cheers,
Dan

LineRenderer is a component that’s added to an object via the menu Components → Miscellaneous → Line Renderer.

Thanks for the reply. Maybe I was unclear though - the question was regarding doing it using scripting only.

How do you create lines using linerenderer from scratch on the fly using scripting?

var lineRenderer : LineRenderer = AddComponent(LineRenderer);
lineRenderer.SetVertexCount(5);
//etc

"var lineRenderer : LineRenderer = " is probably unnecessary, if there is no other renderer on this GO, you can access the LineRenderer via the “renderer” property.

Thanks!
Although the docs for the linerenderer component and the above description then seem a bit off (or, I’m ignorant). :slight_smile:
The docs describe the properties of the linerenderer component as among other things having an array for storing lines in, whereas the class seems to have functions for editing one line (SetVertexCount, etc).

The old examples used a function like AddLine to add a line, then set the properties. Is there an equivalent, or do you simply create a linerenderer and then create lines out of separate segments (ie. 6 verices = 3 lines of 2 vertices each)?

If someone could explain the connection between the class and the array of the component I’d be happy. :slight_smile:

TIA!

According to the documentation, you set the number of line segments using SetVertexCount(number_of_segments) and then set the end positions for each segment using SetPosition(segment_index, some_vector)

SetVertexCount should probably have been called SetSegmentCount… hmmm… I think I’ll report a bug on that.

Alright - but what if you want several, separate lines?
I assume that the SetVertexCount, etc. work on one line and control the number of segments, their positions etc.
From the component docs:

Cool, so the component has an array of lines, each of which has an array of points to connect (which I assume is what’s targeted with SetVertexCount, etc.).
So, how do you adress the array “Lines”. The “AddLine” function used in examples here on the forums prior to version 1.2 isn’t documented, so I assume it is obsolete?

Each line renderer can only render a single row of connected lines.

For every seperate row of lines, you will need to add a new LineRenderer component.

But I see that there is an error in the component documentation. Either the screen shot is wrong or the description of the properties is.

Ok, then it all makes sense. The docs are clearly a bit misleading then, I’d appreciate if you (or someone else with more experience than I) report it. :slight_smile:

Many thanks for the help!

Yes, either the doc is plainly wrong, or the scripting interface is not complete enough.

I have never used the LineRenderer myself, so all my advice has been from reading the docs. I know that the scripting docs are correct (or at least mostly correct), since they are automatically extracted from the source files. The component documentation is written by a human, and has therefore a greater risk of containing some errors and omissions. My bet is that we forgot to update the component docs when we changed the LineRenderer after v. 1.2

I have used the line renderer a lot before. If it has anything more than what is in the docs I have wasted some time because what is in the docs is very bare bones and annoying to use. You can sort of do multiple lines with one line renderer. An example is this lightning effect I made where the line goes out on a specified path and then comes back the same path and then goes out again along a different raycast.

damn yoggy - that’s awesome ; )

I’ve filed a bug report on the docs, as the component documentaion is clearly wrong. (And the scripting docs need some more examples and clarification.)

Isnt this effect a performace hog? That would be really intersting to know.

Going back the same way… could be very interesting, when you scale up the line during its way… especially when it uses transparency…

As always Yoggy… looks really awsome and impressive! :wink:

I actually do use different sizes on the beginning part and end part of the line. Gives it a nice little randomazation actually.

And no, it is actually really really fast. It can handle about 50 lightning bolts no sweat, and 200 if you are feeling confident about your hardware. The hardest part is really the code itself that changes all the lines every frame.

edit: I suppose it is time to do this:

var line : LineRenderer;
var particleEffects : ParticleEmitter[];

var emit = true;
var stopOnNoParent = false;

var myRandomMovement = 0.00;

var followAmount = 0.00;

var countMin = 0.00;
var countMax = 0.00;

var lifetimeMin = 0.00;
var lifetimeMax = 0.00;

var downProbability = 0.00;
var minVelocity = 0.00;
var maxVelocity = 0.00;

var rangeMin = 0.00;
var rangeMax = 0.00;

var vertexDistance = 0.00;
var vetexWander = 0.00;

var textureStretch = 0.00;
var particleHitNormalVelocity = 0.00;


private var myVelocity : Vector3;
private var myAcceleration : Vector3;

private var count = 0;
private var positions : Vector3[];
private var directions : Vector3[];
private var velocities : Vector3[];
private var lifetimes : float[];
private var ranges : float[];

private var hit : RaycastHit;

function Awake ()
{
	count = Random.Range(countMin, countMax);
	positions = new Vector3[count];
	directions = new Vector3[count];
	velocities = new Vector3[count];
	lifetimes = new float[count];
	ranges = new float[count];
	
	i=0;
	while(i < count)
	{
		positions[i] = transform.position;
		
		dir = Random.insideUnitSphere;
		dir += transform.TransformDirection(Vector3.down) * downProbability;
		directions[i] = dir;
		
		velocities[i] =  (-dir + Random.insideUnitSphere) * Random.Range(minVelocity, maxVelocity);
		
		lifetimes[i] = Random.Range(lifetimeMin, lifetimeMax);
		ranges[i] = Random.Range(rangeMin, rangeMax);
	
		i++;	
	}
	
	KillLater();
}


function KillLater()
{
	yield WaitForSeconds (lifetimeMax);
	
	Destroy(gameObject);	
}

function Update ()
{
	if(emit  stopOnNoParent  !transform.parent) emit = false;
	
	myAcceleration += Random.insideUnitSphere * myRandomMovement * Time.deltaTime;
	myVelocity += myAcceleration * Time.deltaTime;
	transform.position += myVelocity * Time.deltaTime;
	
	var totalDistance = 0.00;
	var vertexCount = 0;
	line.SetVertexCount(0);
	
	i=0;
	while(i < count)
	{
		lifetimes[i] -= Time.deltaTime;
		if(lifetimes[i] > 0)
		{
			if((emit || Vector3.Distance(positions[i], transform.position) > 0.1)  followAmount * Time.deltaTime > Random.value) positions[i] = transform.position;
			directions[i] += velocities[i] * Time.deltaTime;
			if((emit || Vector3.Distance(positions[i], transform.position) > 0.1)  Physics.Raycast(positions[i], directions[i], hit, ranges[i]))
			{
				totalDistance += hit.distance * 2;
				points = Mathf.Round(hit.distance / vertexDistance);
								
				vertexCount += 1;
				firstVertex = vertexCount;
				vertexCount += points * 2;
				line.SetVertexCount(vertexCount);
				line.SetPosition(firstVertex - 1, positions[i]);
				
				toHit = firstVertex;
				fromHit = firstVertex + (points * 2);
				i2 = 0;
				while(i2 < points)
				{
					reach = parseFloat(i2 + 1) / parseFloat(points);
					pos = Vector3.Lerp(positions[i], hit.point, reach) + (Random.insideUnitSphere * vetexWander);
					line.SetPosition(toHit, pos);
					line.SetPosition(fromHit - 1, pos);
					i2++;
					toHit++;
					fromHit--;
				}
				
				for(var particleEffect : ParticleEmitter in particleEffects)
				{
					if(!particleEffect) continue;
					pCount = Random.Range(particleEffect.minEmission * Time.deltaTime, particleEffect.maxEmission * Time.deltaTime);
					pIndex = 0;
					while(pIndex < pCount)
					{
						pVelocity = (hit.normal * particleHitNormalVelocity) + 
						Vector3(
						Random.Range(-particleEffect.rndVelocity.x / 2, particleEffect.rndVelocity.x / 2), 
						Random.Range(-particleEffect.rndVelocity.y / 2, particleEffect.rndVelocity.y / 2), 
						Random.Range(-particleEffect.rndVelocity.z / 2, particleEffect.rndVelocity.z / 2) 
						);
					
						size = Random.Range(particleEffect.minSize, particleEffect.maxSize);
						lifetime = Random.Range(particleEffect.minEnergy, particleEffect.maxEnergy);
					
						particleEffect.Emit(pos, pVelocity, size, lifetime, Color.white);
						
						pIndex ++;
					}
				}
				
			}
		}
		
		i++;	
	}
	
	line.renderer.material.mainTextureScale.x = totalDistance / textureStretch;
}

Have fun :wink:

Wow! Very cool effect and awesome to get a peek at the code! Many thanks!

It feels a bit weird to have to retrace the steps to get separate lines, and even then you have to start from the same point. However, I assume having several components for a multitude of fully separate lines won’t slow things down much - if at all.

I’m mainly interested in the linerenderer for use with GUI stuff at this point, so I won’t approach the line count in the lightning bolt example any time soon… :wink:

Again, THANKS! :slight_smile:

hey yog i’m curious - isn’t that the avert fate content in your screenshot? are you working on it as well - what’s the story?

thanks for posting your script i’m definitly going to check it out after work ; )

Thanks Yoggy! I WILL have fun with that.

I have the avert fate content because I was working on it for the otee folks as thier GDC demo. That linerenderer lightning is just one of the cool things I put in. It is a cool universal script so I thought I would share it.

Using multiple lines instead of careful retracing of steps and other tricks will slow it down because you are adding draw calls. For a gui I would recomend using GUITextures with pixel inset and laboriously creating everything from code, if you are up to it. Lines could work, I don’t know what your situation is.

that’s really cool yog - both the effect and sharing.