В репо CS_ProceduralCities есть оболочки для создания дорог на Builder.cs
ushort MakeSegment(Vector3 start, Vector3 end, Vector3 startDirection, Vector3 endDirection, uint prefabId) {
{
var netManager = Singleton<NetManager>.instance;
ushort segmentId;
if (netManager.CreateSegment(out segmentId, ref SimulationManager.instance.m_randomizer, PrefabCollection<NetInfo>.GetPrefab(prefabId), GetNode(start), GetNode(end), startDirection, endDirection, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, false)) {
++SimulationManager.instance.m_currentBuildIndex;
//DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "made segment");
} else {
throw new Exception("Error creating segment");
}
return segmentId;
}
;
}
ushort MakeSegment(Vector3 start, Vector3 end, bool flip, uint prefabId) {
if (flip) {
var temp = start;
start = end;
end = temp;
}
var netManager = Singleton<NetManager>.instance;
ushort segmentId;
Vector3 direction = new Vector3(end.x - start.x, end.y - start.y, end.z - start.z).normalized;
if (netManager.CreateSegment(out segmentId, ref SimulationManager.instance.m_randomizer, PrefabCollection<NetInfo>.GetPrefab(prefabId), GetNode(start), GetNode(end), direction, -direction, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, false)) {
++SimulationManager.instance.m_currentBuildIndex;
//DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "made segment");
} else {
throw new Exception("Error creating segment");
}
return segmentId;
}
void MakeRoad(Vector3 start, Vector3 end, Vector3 startDirection, Vector3 endDirection, bool flip, uint prefabId) {
DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "making bezier road");
if (flip) {
Vector3 temp = start;
start = end;
end = temp;
temp = -startDirection;
startDirection = -endDirection;
endDirection = temp;
}
float length = (end - start).magnitude;
var curve = new Bezier3(start, start + startDirection * length / 3, end + endDirection * length / 3, end);
Vector3 priorPos = curve.Position(0);
Vector3 priorDir = curve.Tangent(0).normalized;
float t = curve.Travel(0, pitch);
DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, t.ToString());
while (t < .9999) {
Vector3 pos = curve.Position(t);
Vector3 dir = curve.Tangent(t);
MakeSegment(priorPos, pos, priorDir, -dir, prefabId);
t = curve.Travel(t, pitch);
DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, t.ToString());
priorPos = pos;
priorDir = dir;
}
{
Vector3 pos = curve.Position(1);
Vector3 dir = curve.Tangent(1).normalized;
MakeSegment(priorPos, pos, priorDir, -dir, prefabId);
}
}
void MakeRoad(Vector3 start, Vector3 end, bool flip, uint prefabId) {
if (flip) {
Vector3 temp = start;
start = end;
end = temp;
}
var dir = (end - start).normalized;
if ((dir.x == 0 || dir.z == 0) && dir.y == 0) {
if (dir.x > 0) {
//DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "made +x vector road");
for (float x = start.x; x < end.x; x += pitch) {
float clampedIncrement = x + pitch;
if (clampedIncrement > end.x) clampedIncrement = end.x;
MakeSegment(new Vector3(x, start.y, start.z), new Vector3(clampedIncrement, start.y, start.z), false, prefabId);
}
} else if (dir.x < 0) {
//DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "made -x vector road");
for (float x = start.x; x > end.x; x -= pitch) {
float clampedIncrement = x - pitch;
if (clampedIncrement < end.x) clampedIncrement = end.x;
MakeSegment(new Vector3(x, start.y, start.z), new Vector3(clampedIncrement, start.y, start.z), false, prefabId);
}
} else if (dir.z > 0) {
//DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "made +z vector road");
for (float z = start.z; z < end.z; z += pitch) {
float clampedIncrement = z + pitch;
if (clampedIncrement > end.z) clampedIncrement = end.z;
MakeSegment(new Vector3(start.x, start.y, z), new Vector3(start.x, start.y, clampedIncrement), false, prefabId);
}
} else if (dir.z < 0) {
//DebugOutputPanel.AddMessage(PluginManager.MessageType.Warning, "made -z vector road");
for (float z = start.z; z > end.z; z -= pitch) {
float clampedIncrement = z - pitch;
if (clampedIncrement < end.z) clampedIncrement = end.z;
MakeSegment(new Vector3(start.x, start.y, z), new Vector3(start.x, start.y, clampedIncrement), false, prefabId);
}
} else {
throw new Exception("logic error");
}
} else {
var delta = end - start;
var direction = delta.normalized;
var length = delta.magnitude;
float t = 0;
for (; t <= length - pitch; t += pitch) {
MakeSegment(start + direction * t, start + direction * (t + pitch), false, prefabId);
}
MakeSegment(start + direction * t, end, false, prefabId);
}
}