- Home /
Suggestions for improvements of custom trail-drawing script highly appreciated.
I'm working on a project involving an AI agent to be trained to navigate around a environment, and I want to visualise how the movement pattern change as training progresses. I started out by using the build-in component TrailRenderer but the inclusion of jumps, from where the current training session ends to the start position, annoyed me and and so I wrote my own custom implementation.
I wanted my implementation to have three abilities; The possibility to restrict the number of trails visible, changing alpha on the trails drawn based on their relevance and to not include jumps, as when using the TrailRenderer component.
The biggest hurtle of my own implementation at the moment, as I see it, is that some of the trails can end up consisting of a huge number of points (maximum number of points witness so far are 30000+), if the environment is challenging enough, which slows down the training tremendously. I have no idea how to improve on that hurtle, other than adding a time delay, such that a new point is only added every, let's say, 0.5 second. However, larger time delays results in greater inaccuracy in the visualised trails, and so constrains the value the trails provide.
Training (500000 steps) takes, without trail drawing, around 45 minutes on my machine. With my implementation for drawing trails, and 0.5 seconds time delay, does around 220000 training steps take 1.5 hour, after which I decided to stop training.
My implementation consists of two parts; A script, which is attached to the agent, which draws the current trail, with the possibility of adding a time delay. The second part is not a script itself but a part of the AgentReset() method, which has two purposes; Adding/Removing trails at run time and changing alpha of the trails, depending on how relevant they are, i.e. newest trails has highest alpha.
Below is the script attached to the agent,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class drawDynamicTrail : MonoBehaviour
{
private GameObject[] trails;
private int traceStep = 0;
private int traceNumber = 0;
private int currentTrace;
private LineRenderer lr;
private float timeToDraw = 0;
public bool drawTrails = false;
void Update()
{
if (drawTrails){
if (Time.time > timeToDraw)
{
trails = GameObject.FindGameObjectsWithTag("Trail");
if (trails.Length != traceNumber)
{
traceNumber = trails.Length;
traceStep = 0;
} else
{
currentTrace = traceNumber - 1;
lr = trails[currentTrace].GetComponent<LineRenderer>();
if (traceStep >= lr.positionCount)
{
lr.positionCount = traceStep + 1;
}
lr.SetPosition(traceStep,transform.position);
traceStep += 1;
}
timeToDraw = Time.time + 0.5f;
}
}
}
}
and below here is the part of the AgentReset() method.
// Updating the trails
if (drawTrails)
{
trails = GameObject.FindGameObjectsWithTag("Trail");
// Deciding on whether to simply add a a trail or remove one before adding (if the
number of trails is equal to the maximum specified).
if (trails.Length < NumberOfTrails)
{
createTrail();
} else
{
// Updating
Destroy(trails[0]);
createTrail();
}
// Changing Alpha on the trails
// Extended implementation
if (trails.Length % 10 == 0 && trails.Length != 0)
{
int step = trails.Length / 10;
int stepFloor = 0;
int stepRoof = step;
for (int i = 0;i<trails.Length;i++)
{
// Deciding on the level of alpha
if (i >= stepFloor && i < stepRoof)
{
alpha = ((float)stepRoof / trails.Length);
} else
{
stepRoof += step;
stepFloor += step;
alpha = ((float)stepRoof / trails.Length);
}
// Setting the alpha level
lrC = trails[i].GetComponent<LineRenderer>();
if (lrC.positionCount > maximumPositions)
{
maximumPositions = lrC.positionCount;
//Debug.Log("The maximum number of positions are: " + maximumPositions);
}
Gradient gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(Color.blue,0.0f),
new GradientColorKey(Color.blue,1.0f)},
new GradientAlphaKey[] { new GradientAlphaKey(alpha, 0.0f),
new GradientAlphaKey(alpha, 1.0f)}
);
lrC.colorGradient = gradient;
}
}
}
I'm happy to provide the entire AgentReset() method if needed, but it is left out for now, as that part isn't the origin of my biggest hurtle, as I see it.
All suggestions are highly appreciated.
Your answer
Follow this Question
Related Questions
Drawing and saving during gameplay 0 Answers
3d object outline shader 1 Answer
Draw trail behind player when its not moving 0 Answers
Object trail/tail 1 Answer
How do I draw directly (and quickly) into the rendered frame? 1 Answer