I'm trying to create a road with some lines on it programmatically.
I add the control points to the shape.
Then I add MetaCGOptions to the control points.
I set the hard edge and material options on the control point.
But then when the shape is build, the options are set back to default again in the scene.
If I mark the shape spline as dirty, the metadata is gone instantly.
Sync from hierarchy results in the same.
What is the right way to make that meta data stick?
I add the control points to the shape.
Then I add MetaCGOptions to the control points.
I set the hard edge and material options on the control point.
But then when the shape is build, the options are set back to default again in the scene.
If I mark the shape spline as dirty, the metadata is gone instantly.
Sync from hierarchy results in the same.
What is the right way to make that meta data stick?
Code:
public static Vector3[] ShapeSplinePositions(CurvySpline roadShape, int roadMaterial, float width,
float offsetY,
float heightUnderGround,
float offsetX,
IList<RoadLineObject> roadLines)
{
/*
* c = count
* shiftRight = how much the road is moved to the right of the center line.
* <- width ->
* <-> offsetX = -0.5
* 0╔══[1═2]═|═════[3═4]═══╗c-3
* ║ offsetY ║
* ───╫──────────────────────╫────── terrain / control points
*░░░░║░░Height░under░ground░║░░░░░░
*░░░░║░░░░░░░░░░░░░░░░░░░░░░║░░░░░░
*░c-1╚══════════════════════╝c-2░░░
*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
*/
//make a clockwise shape
var halfWidth = Mathf.Abs(width / 2f);
var count = 4 + roadLines.Count * 2;
var positions = new Vector3[count];
//left
positions[0] = new Vector3(offsetX - halfWidth, offsetY, 0);
//the top surface.
for (int i = 0; i < roadLines.Count; i++)
{
positions[i * 2 + 1] = new Vector3(offsetX -halfWidth + roadLines[i].Location, offsetY, 0);
positions[i * 2 + 2] = new Vector3(offsetX -halfWidth + roadLines[i].Location + roadLines[i].Width, offsetY, 0);
}
//right
positions[count-3] = new Vector3(offsetX + halfWidth, offsetY, 0);
//right down
positions[count-2] = new Vector3(offsetX + halfWidth, -heightUnderGround, 0);
//left down
positions[count-1] = new Vector3(offsetX - halfWidth, -heightUnderGround, 0);
var segment = roadShape.Add(positions);
return positions;
}
private static void SetControlPointMetaData(int roadMaterial, IList<RoadLineObject> roadLines, IList<CurvySplineSegment> segment, int count)
{
{
var left = segment[0];
var leftCG = left.GetMetadata<MetaCGOptions>(true);
leftCG.MaterialID = roadMaterial;
leftCG.HardEdge = true;
}
for (var i = 0; i < roadLines.Count; i++)
{
var leftControlPoint = segment[i * 2 + 1];
var leftCG = leftControlPoint.GetMetadata<MetaCGOptions>(true);
leftCG.MaterialID = roadLines[i].Material;
leftCG.HardEdge = true;
var rightControlPoint = segment[i * 2 + 2];
var rightCG = rightControlPoint.GetMetadata<MetaCGOptions>(true);
rightCG.MaterialID = roadMaterial;
rightCG.HardEdge = true;
}
{
//from top right to bottom right
var controlPoint = segment[count - 3];
var controlPointCG = controlPoint.GetMetadata<MetaCGOptions>(true);
controlPointCG.MaterialID = 0;
controlPointCG.HardEdge = true;
}
{
//from bottom right to bottom left
var controlPoint = segment[count - 3];
var controlPointCG = controlPoint.GetMetadata<MetaCGOptions>(true);
controlPointCG.MaterialID = 0;
controlPointCG.HardEdge = true;
}
{
//from bottom left to top left
var controlPoint = segment[count - 3];
var controlPointCG = controlPoint.GetMetadata<MetaCGOptions>(true);
controlPointCG.MaterialID = 0;
controlPointCG.HardEdge = true;
}
}
private void BuildUpLines()
{
var markers = new List<RoadLineObject>(roadLineMarkers);
markers.Sort((a, b) => a.Location.CompareTo(b.Location));
RoadShape.Clear();
var positions = ShapeSplinePositions(RoadShape, roadMaterial, width, _offsetY, _heightUnderGround, _offsetX, markers);
SetControlPointMetaData(roadMaterial, markers, RoadShape.ControlPointsList, RoadShape.ControlPointsList.Count);
SetRoadTextureAndTiling();
RoadShape.SetDirtyAll();
}