06-18-2018, 10:27 PM
I need to figure out how to spawn objects (in this case vehicles) that are of different lengths with uniform spacing along a spline (in this case representing a road). I'm having a lot of trouble getting this to work correctly though, it seems like the longer objects always throw off everything else down the line and I wind up with results that are just completely not correct.
I figured out how to get objects spawning MOSTLY uniformly using this approach...
but since it doesnt take into account the length of the objects being spawned it can lead to serious issues with cars spawning inside a sufficiently long car in from of them. My efforts to incorporate vehicle length have pretty much failed, and I'm open to any suggestions on how to get this actually working correctly. here is how that is looking right now.
I figured out how to get objects spawning MOSTLY uniformly using this approach...
Code:
[ContextMenu("Spawn Vehicles")]
private void EditorSpawn()
{
int startIndex = 0;
int size = spline.ControlPointsList.Count - startIndex;
float[] distances = new float[size]; // node distances
Vector3 lastPosition = spline.ControlPointsList[0].transform.position;
//populate the node distances
float distance = 0;
for (int i = 0; i < size; i++)
{
int index = i + startIndex;
Vector3 nodePosition = spline.ControlPointsList[index].transform.position; // define the vertices based on the nodes:
distance += (nodePosition - lastPosition).magnitude;
distances[i] = distance; // distance along the path
lastPosition = nodePosition;
}
// find the desired distance between objects:
float spacing = distance / (SpawnCount - 1); // initialize conditions to create 1st object
lastPosition = spline.ControlPointsList[startIndex].position;
int curNode = startIndex;
float objectDistance = 0f;
float lastDistance = 0f;
for (int i = 0; i < SpawnCount; i++)
{
// find direction and position of current segment:
Vector3 dir = (spline.ControlPointsList[curNode].position - lastPosition).normalized;
Vector3 pos = lastPosition + dir * (objectDistance - lastDistance);
//spawn and initialize vehicle
CurvyVehicle vehicle = (CurvyVehicle)UnityEditor.PrefabUtility.InstantiatePrefab(GetPrefab());
vehicle.transform.SetParent(ParentTransform);
vehicle.Controller.Spline = spline;
vehicle.Controller.InitialPosition = spline.GetNearestPointTF(pos);
vehicle.Speed = vehicleSpeed;
objectDistance += spacing;
// find next object distance
// find segment where to put next object:
while (objectDistance > distances[curNode] && curNode < size - 1)
{
lastPosition = spline.ControlPointsList[curNode].position;
lastDistance = distances[curNode];
curNode++;
}
}
}
but since it doesnt take into account the length of the objects being spawned it can lead to serious issues with cars spawning inside a sufficiently long car in from of them. My efforts to incorporate vehicle length have pretty much failed, and I'm open to any suggestions on how to get this actually working correctly. here is how that is looking right now.
Code:
[ContextMenu("Spawn Vehicles Alt")]
private void EditorSpawnAlt()
{
int startIndex = 0;
int size = spline.ControlPointsList.Count - startIndex;
float[] distances = new float[size]; // node distances
Vector3 lastPosition = spline.ControlPointsList[0].transform.position;
//populate the node distances
float distance = 0;
for (int i = 0; i < size; i++)
{
int index = i + startIndex;
Vector3 nodePosition = spline.ControlPointsList[index].transform.position; // define the vertices based on the nodes:
distance += (nodePosition - lastPosition).magnitude;
distances[i] = distance; // distance along the path
lastPosition = nodePosition;
}
//need to populate vehicles so we know lengths ahead of time!
CurvyVehicle[] spawnedVehicles = new CurvyVehicle[spawnCount];
float totalVehicleLength = 0f;
for (int i = 0; i < spawnCount; i++)
{
CurvyVehicle vehicle = (CurvyVehicle)UnityEditor.PrefabUtility.InstantiatePrefab(GetPrefab());
vehicle.transform.SetParent(ParentTransform);
vehicle.Controller.Spline = spline;
vehicle.Speed = vehicleSpeed;
totalVehicleLength += vehicle.VehicleLength;
spawnedVehicles[i] = vehicle;
}
// find the desired distance between objects:
lastPosition = spline.ControlPointsList[startIndex].position;
int curNode = startIndex;
float objectDistance = 0f;
float lastDistance = 0f;
float spacing = 0f;
float offset = ((distance - totalVehicleLength) / (SpawnCount - 1));
//now we need to iterate through the vehicles now that we know all the lengths
for (int i = 0; i < spawnedVehicles.Length; i++)
{
// find direction and position of current segment:
spacing = offset + spawnedVehicles[i].VehicleLength;
Vector3 dir = (spline.ControlPointsList[curNode].position - lastPosition).normalized;
Vector3 pos = lastPosition + dir * (objectDistance - lastDistance);
//spawn and initialize vehicle
spawnedVehicles[i].Controller.InitialPosition = spline.GetNearestPointTF(pos);
objectDistance += spacing;
// find next object distance
// find segment where to put next object:
while (objectDistance > distances[curNode] && curNode < size - 1)
{
lastPosition = spline.ControlPointsList[curNode].position;
lastDistance = distances[curNode];
curNode++;
}
}
}