diff --git a/Source/InstancedMeshLineRendering/Private/GPUInstancedLineComponent.cpp b/Source/InstancedMeshLineRendering/Private/GPUInstancedLineComponent.cpp
index 4b2acaa3614f85c672d4453f6c3a11a493a60c13..247356b1ccdfed6d77209320c36640967a3bb6ec 100644
--- a/Source/InstancedMeshLineRendering/Private/GPUInstancedLineComponent.cpp
+++ b/Source/InstancedMeshLineRendering/Private/GPUInstancedLineComponent.cpp
@@ -4,7 +4,7 @@
 #include "GPUInstancedLineComponent.h"
 #include "InstancedMeshLineRendering.h" // Only needed for logging
 
-//#pragma optimize("", off)
+#pragma optimize("", off)
 
 
 UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer)
@@ -24,6 +24,12 @@ UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer&
 	UMaterial* LineMaterial = LineMaterialAsset.Object;
 	SetStaticMesh(LineAsset);
 	SetMaterial(0, LineMaterial);
+
+	
+	UMaterialInterface* LineMaterialInterface = LoadObject<UMaterialInterface>(NULL, TEXT("/InstancedMeshLineRendering/DynamicLineMaterial.DynamicLineMaterial"), NULL, LOAD_None, NULL);
+	DynamicLineMaterial = UMaterialInstanceDynamic::Create(LineMaterialInterface, GetTransientPackage());
+	check(DynamicLineMaterial);
+	
 	
 	// three color values + width + 1 texture index value
 	// r | g | b | w | i_T 
@@ -31,6 +37,7 @@ UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer&
 
 	CurrentTextureMarker = FIntPoint(0, 0);
 	CurrentTextureIndex = 0,
+	NextFreeId = 0;
 	
 	TextureWidth = 2048;
 	TextureHeight = 2048;
@@ -83,36 +90,37 @@ void UGPUInstancedLineComponent::UpdateWholeTexture()
 
 void UGPUInstancedLineComponent::Init()
 {
+	if(PositionTexture != nullptr)
+	{
+		UE_LOG(LogLineRendering, Error, TEXT("UGPUInstancedLineComponent::Init PositionTexture already exists!"));
+	}
 	UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Creating Texture"));
 	PositionTexture = UTexture2D::CreateTransient(TextureWidth, TextureHeight, PF_A32B32G32R32F);
 	// Allocate the texture RHI
 	PositionTexture->UpdateResource();
 
-	UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Creating MID"));
-	
-	DynamicLineMaterial = CreateAndSetMaterialInstanceDynamic(0);// UMaterialInstanceDynamic::Create(LineMat, this, "DynamicLineMaterialMID");
 	if (DynamicLineMaterial == nullptr) // FOR WHATEVER REASON I HAVE NO IDEA
 	{
-		DynamicLineMaterial = UMaterialInstanceDynamic::Create(GetStaticMesh()->GetMaterial(0), this);// UMaterialInstanceDynamic::Create(LineMat, this, "DynamicLineMaterialMID");
-		SetMaterial(0, DynamicLineMaterial);
+		UE_LOG(LogLineRendering, Fatal, TEXT("UGPUInstancedLineComponent::Init MID was nullptr!"));
 	}
-	if(DynamicLineMaterial)
+	else
 	{
+		UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Setting MID"));
+
+		SetMaterial(0, DynamicLineMaterial);
 		DynamicLineMaterial->SetTextureParameterValue("PositionTexture", PositionTexture);
 		DynamicLineMaterial->SetScalarParameterValue("TextureWidth", TextureWidth);
 	}
-	else
-		UE_LOG(LogLineRendering, Error, TEXT("UGPUInstancedLineComponent::Init DynamicLineMaterial was nullptr"));
 
-	UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Resetting Data"));
-	LineMap.Empty();
-	LinearLineData.Empty();
-	NextFreeId = 0;
-	CurrentTextureIndex = 0;
-	CurrentTextureMarker = FIntPoint(0, 0);
-	ClearInstances();
+	//UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Resetting Data"));
+	//LineMap.Empty();
+	//LinearLineData.Empty();
+	//NextFreeId = 0;
+	//CurrentTextureIndex = 0;
+	//CurrentTextureMarker = FIntPoint(0, 0);
+	//ClearInstances();
 
-	RegisterSerializedEditorLines();
+	//RegisterSerializedEditorLines();
 
 	bIsInitialized = true;
 
@@ -121,23 +129,28 @@ void UGPUInstancedLineComponent::Init()
 	//{
 	//	AddLineFromEditorData(EditorLine);
 	//}
-	
-}
 
-void UGPUInstancedLineComponent::RegisterSerializedEditorLines()
-{
+	// Update the texture
 
-	// Here's to hoping the respective id field doesn't get serialized...
-
-	for (FEditorLineData& EditorLine : EditorLines)
-	{
-		if(EditorLine.RespectiveLineId == -1)
-		{
-			AddLineFromEditorData(EditorLine);
-		}
-	}	
+	// Theoretically we could serialize the texture as well, but that seems like too much work
+	UpdateWholeTexture();
+	
 }
 
+//void UGPUInstancedLineComponent::RegisterSerializedEditorLines()
+//{
+//
+//	// Here's to hoping the respective id field doesn't get serialized...
+//
+//	for (FEditorLineData& EditorLine : EditorLines)
+//	{
+//		if(EditorLine.RespectiveLineId == -1 || !LineMap.Contains(EditorLine.RespectiveLineId))
+//		{
+//			AddLineFromEditorData(EditorLine);
+//		}
+//	}	
+//}
+
 void UGPUInstancedLineComponent::UpdateAllEditorLines()
 {
 	for (const FEditorLineData& EditorLine : EditorLines)
@@ -224,7 +237,7 @@ void UGPUInstancedLineComponent::BeginPlay()
 	Super::BeginPlay();
 
 	// todo don't think this is needed here
-	RegisterSerializedEditorLines();
+	//RegisterSerializedEditorLines();
 	
 	//Init();
 	if(!bIsInitialized)
@@ -245,7 +258,7 @@ void UGPUInstancedLineComponent::PostInitProperties()
 #if WITH_EDITOR
 void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
 {
-	if (PropertyChangedEvent.Property != NULL)
+	if (PropertyChangedEvent.Property != NULL && bIsInitialized)
 	{
 		if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UGPUInstancedLineComponent, EditorLines))
 		{
@@ -467,6 +480,14 @@ void UGPUInstancedLineComponent::BeginDestroy()
 	ReleaseData();
 }
 
+void UGPUInstancedLineComponent::Serialize(FArchive& Ar)
+{
+	Super::Serialize(Ar);
+
+
+	
+}
+
 void UGPUInstancedLineComponent::ReserveMemory(int32 NumberOfSegments, int32 NumberOfLines)
 {
 	const int32 Total = NumberOfSegments * NumberOfLines;
@@ -496,14 +517,14 @@ bool UGPUInstancedLineComponent::ResizeTexture(int32 Width, int32 Height)
 	// This might be a bit awkward as the line map is a *map*, and not just an array.
 	// Some lines might be re-ordered in the texture, but that should be fine.
 	
-	for(TPair<int32, GPULineArray>& Line : LineMap)
+	for(TPair<int32, FGPULineArray>& Line : LineMap)
 	{
-		for (GPULineIndices& LineIndices : Line.Value)
+		for (FGPULineIndices& LineIndices : Line.Value.IndexArray)
 		{
 			// Key is instance id, value is texture index.
-			if(LineIndices.Key >= 0)
-				SetCustomDataValue(LineIndices.Key, 4, CurrentTextureIndex, false);
-			LineIndices.Value = CurrentTextureIndex;
+			if(LineIndices.InstanceIndex >= 0)
+				SetCustomDataValue(LineIndices.InstanceIndex, 4, CurrentTextureIndex, false);
+			LineIndices.TextureIndex = CurrentTextureIndex;
 			CurrentTextureIndex++;
 			MoveTextureMarker();
 		}
@@ -556,8 +577,8 @@ void UGPUInstancedLineComponent::InitializeLinesInBulk(int32 NumberOfLines, int3
 		const FLinearColor Color = UniformColor ? Colors[0] : Colors[LineIndex];
 		const float Width = UniformWidth ? Widths[0] : Widths[LineIndex];
 
-		GPULineArray& NewLineArray = LineMap.Add(NextFreeId, GPULineArray());
-		NewLineArray.Reserve(NumberOfSegmentsPerLine + 1);
+		FGPULineArray& NewLineArray = LineMap.Add(NextFreeId, FGPULineArray());
+		NewLineArray.IndexArray.Reserve(NumberOfSegmentsPerLine + 1);
 		
 		for (int32 PointIndex = 0; PointIndex < NumberOfSegmentsPerLine; ++PointIndex)
 		{
@@ -568,12 +589,12 @@ void UGPUInstancedLineComponent::InitializeLinesInBulk(int32 NumberOfLines, int3
 			SetCustomDataValue(InstanceId, 2, Color.B, false);
 			SetCustomDataValue(InstanceId, 3, Width, false);
 			SetCustomDataValue(InstanceId, 4, static_cast<float>(CurrentTextureIndex), false); // Segment Start
-			NewLineArray.Add(TPair<int32, int32>{InstanceId, LineIndex * (NumberOfSegmentsPerLine + 1) + PointIndex});
+			NewLineArray.IndexArray.Add({InstanceId, LineIndex * (NumberOfSegmentsPerLine + 1) + PointIndex});
 			CurrentTextureIndex++;
 
 			MoveTextureMarker();
 		}
-		NewLineArray.Add(TPair<int32, int32>{-1, LineIndex * (NumberOfSegmentsPerLine + 1) + NumberOfSegmentsPerLine});
+		NewLineArray.IndexArray.Add({-1, LineIndex * (NumberOfSegmentsPerLine + 1) + NumberOfSegmentsPerLine});
 		MoveTextureMarker();
 		CurrentTextureIndex++;
 		NextFreeId++;
@@ -592,8 +613,8 @@ int32 UGPUInstancedLineComponent::AddLine(const TArray<FVector>& Line, FLinearCo
 		return -1;
 	}
 	// 1.
-	GPULineArray& NewLineArray = LineMap.Add(NextFreeId, GPULineArray());
-	NewLineArray.Reserve(Line.Num());
+	FGPULineArray& NewLineArray = LineMap.Add(NextFreeId, FGPULineArray());
+	NewLineArray.IndexArray.Reserve(Line.Num());
 
 	const int32 LineId = NextFreeId;
 	NextFreeId++; // TODO Fix Id system as this can possibly overflow.
@@ -613,13 +634,13 @@ int32 UGPUInstancedLineComponent::AddLine(const TArray<FVector>& Line, FLinearCo
 		SetCustomDataValue(InstanceId, 2, Color.B, false);
 		SetCustomDataValue(InstanceId, 3, Width, false);		
 		SetCustomDataValue(InstanceId, 4, static_cast<float>(CurrentTextureIndex), false); // Segment Start
-		NewLineArray.Add(TPair<int32, int32>{InstanceId, LinearLineData.Num() + PointIndex});
+		NewLineArray.IndexArray.Add({InstanceId, LinearLineData.Num() + PointIndex});
 		CurrentTextureIndex++;
 
 		MoveTextureMarker();		
 	}
 	// Add the last point which does not correspond to a transform/instance, but needs to be added to the texture still such that the second last instance can read it:
-	NewLineArray.Add(TPair<int32, int32>{-1, LinearLineData.Num() + NumberSegments});
+	NewLineArray.IndexArray.Add({-1, LinearLineData.Num() + NumberSegments});
 	MoveTextureMarker();
 	CurrentTextureIndex++;
 
@@ -670,18 +691,18 @@ bool UGPUInstancedLineComponent::AddPoint(int32 LineId, const FVector& Point)
 	// Adding a point to the last line is easy. Adding it to a line the middle is awkward and requires an almost complete recalculation
 
 	// Get color and width of the line
-	GPULineArray& Line = LineMap[LineId];
+	FGPULineArray& Line = LineMap[LineId];
 
 	
-	const float R = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats];
-	const float G = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 1];
-	const float B = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 2];
-	const float Width = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 3];
+	const float R = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats];
+	const float G = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 1];
+	const float B = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 2];
+	const float Width = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 3];
 
 	const FIntPoint InitialTextureMarker = CurrentTextureMarker;
 	// Check if it's the last line:
 
-	GPULineIndices& Indices = Line.Last();
+	FGPULineIndices& Indices = Line.IndexArray.Last();
 	const int32 InstanceId = AddInstanceWorldSpace(FTransform::Identity);
 	SetCustomDataValue(InstanceId, 0, R, false);
 	SetCustomDataValue(InstanceId, 1, G, false);
@@ -689,11 +710,11 @@ bool UGPUInstancedLineComponent::AddPoint(int32 LineId, const FVector& Point)
 	SetCustomDataValue(InstanceId, 3, Width, false);
 	
 	// Update the latest dummy entry to point to the actual segment.
-	Line.Last().Key = InstanceId;
+	Line.IndexArray.Last().InstanceIndex = InstanceId;
 	// Set remaining custom data for the newly created segment:
-	SetCustomDataValue(InstanceId, 4, static_cast<float>(Indices.Value), false); // Segment Start
+	SetCustomDataValue(InstanceId, 4, static_cast<float>(Indices.TextureIndex), false); // Segment Start
 	
-	FVector4& PreviousLastPoint = LinearLineData[Indices.Value];
+	FVector4& PreviousLastPoint = LinearLineData[Indices.TextureIndex];
 	PreviousLastPoint.W = 1.0; // This isn't the line end anymore.
 
 	if(LineId == NextFreeId - 1)
@@ -702,7 +723,7 @@ bool UGPUInstancedLineComponent::AddPoint(int32 LineId, const FVector& Point)
 		LinearLineData.Add(FVector4(Point, -1)); // This is the last point now.
 		
 		// Add a new dummy entry for the last point
-		Line.Add(GPULineIndices{ -1, LinearLineData.Num() - 1 });		
+		Line.IndexArray.Add(FGPULineIndices{ -1, LinearLineData.Num() - 1 });		
 		
 		CurrentTextureIndex++;	
 		MoveTextureMarker();
@@ -756,26 +777,26 @@ bool UGPUInstancedLineComponent::AddPoint(int32 LineId, const FVector& Point)
 	// This is slightly more complicated as all the indices after the added point need to be adjusted.
 	// Additionally, the point needs to be inserted into the texture, shifting the whole thing. 
 
-	const int32 NewPointTextureIndex = Indices.Value + 1;
+	const int32 NewPointTextureIndex = Indices.TextureIndex + 1;
 
 	// Update all LineMap Indices that have a texture index larger than the newly inserted point. Todo: Make more efficient, maybe remove map and swap to array:
-	for (TPair<int32, GPULineArray>& Pair : LineMap)
+	for (TPair<int32, FGPULineArray>& Pair : LineMap)
 	{
-		GPULineArray& LineArray = Pair.Value;
-		if (LineArray[0].Value >= NewPointTextureIndex)
+		FGPULineArray& LineArray = Pair.Value;
+		if (LineArray.IndexArray[0].TextureIndex >= NewPointTextureIndex)
 		{
 			// Need to increase all indices by 1 and adjust the custom data
-			for (int32 i = 0; i < LineArray.Num(); ++i)
+			for (int32 i = 0; i < LineArray.IndexArray.Num(); ++i)
 			{
-				LineArray[i].Value++;
-				SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);				
+				LineArray.IndexArray[i].TextureIndex++;
+				SetCustomDataValue(LineArray.IndexArray[i].InstanceIndex, 4, LineArray.IndexArray[i].TextureIndex, false);
 			}
 		}
 	}
 	// Insert the point into the LinearData:
 	LinearLineData.Insert(FVector4(Point, -1), NewPointTextureIndex);
 	// Add it to the LineMap - this is the new dummy segment because we add it at the end of the line
-	Line.Add(GPULineIndices{ -1, NewPointTextureIndex });
+	Line.IndexArray.Add(FGPULineIndices{ -1, NewPointTextureIndex });
 	//SetCustomDataValue(InstanceId, 4, NewPointTextureIndex, true);
 	
 	CurrentTextureIndex++;
@@ -792,15 +813,15 @@ bool UGPUInstancedLineComponent::InsertPoint(int32 LineId, int32 SegmentId, cons
 {
 	TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::InsertPoint"))
 
-	GPULineArray& Line = LineMap[LineId];
+	FGPULineArray& Line = LineMap[LineId];
 
-	if (SegmentId == Line.Num())
+	if (SegmentId == Line.IndexArray.Num())
 	{
 		return AddPoint(LineId, Point);
 	}	
-	const float Width = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 3];
+	const float Width = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 3];
 
-	const int32 LinearDataIndex = Line[SegmentId].Value;
+	const int32 LinearDataIndex = Line.IndexArray[SegmentId].TextureIndex;
 
 	// Add a new segment BEFORE the current one.
 	const int32 InstanceId = AddInstanceWorldSpace(FTransform::Identity);
@@ -819,27 +840,27 @@ bool UGPUInstancedLineComponent::InsertPoint(int32 LineId, int32 SegmentId, cons
 		// This was the old start point
 		LinearLineData[LinearDataIndex + 1].W = 1;
 	}	
-	Line.Insert(GPULineIndices{ InstanceId, LinearDataIndex }, SegmentId);
+	Line.IndexArray.Insert(FGPULineIndices{ InstanceId, LinearDataIndex }, SegmentId);
 	SetCustomDataValue(InstanceId, 4, LinearDataIndex, false);
 
 	// Update the rest of the line
-	for(int32 i = SegmentId + 1; i < Line.Num(); ++i)
+	for(int32 i = SegmentId + 1; i < Line.IndexArray.Num(); ++i)
 	{
-		Line[i].Value++;
-		SetCustomDataValue(Line[i].Key, 4, Line[i].Value);
+		Line.IndexArray[i].TextureIndex++;
+		SetCustomDataValue(Line.IndexArray[i].InstanceIndex, 4, Line.IndexArray[i].TextureIndex);
 	}
 
 	// Update all following lines
-	for (TPair<int32, GPULineArray>& Pair : LineMap)
+	for (TPair<int32, FGPULineArray>& Pair : LineMap)
 	{
-		GPULineArray& LineArray = Pair.Value;
-		if (LineArray[0].Value > LinearDataIndex)
+		FGPULineArray& LineArray = Pair.Value;
+		if (LineArray.IndexArray[0].TextureIndex > LinearDataIndex)
 		{
 			// Need to increase all indices by 1 and adjust the custom data
-			for (int32 i = 0; i < LineArray.Num(); ++i)
+			for (int32 i = 0; i < LineArray.IndexArray.Num(); ++i)
 			{
-				LineArray[i].Value++;
-				SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);
+				LineArray.IndexArray[i].TextureIndex++;
+				SetCustomDataValue(LineArray.IndexArray[i].InstanceIndex, 4, LineArray.IndexArray[i].TextureIndex, false);
 			}
 		}
 	}
@@ -857,10 +878,10 @@ bool UGPUInstancedLineComponent::InsertPoint(int32 LineId, int32 SegmentId, cons
 
 bool UGPUInstancedLineComponent::InsertPointWithSameColor(int32 LineId, int32 SegmentId, const FVector& Point)
 {
-	GPULineArray& Line = LineMap[LineId];	
-	const float R = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats];
-	const float G = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 1];
-	const float B = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 2];
+	FGPULineArray& Line = LineMap[LineId];	
+	const float R = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats];
+	const float G = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 1];
+	const float B = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 2];
 
 	return InsertPoint(LineId, SegmentId, Point, { R, G, B });
 }
@@ -878,18 +899,18 @@ bool UGPUInstancedLineComponent::AddPoints(int32 LineId, const TArray<FVector>&
 	// Adding a point to the last line is easy. Adding it to a line the middle is awkward and requires an almost complete recalculation
 
 	// Get color and width of the line
-	GPULineArray& Line = LineMap[LineId];
-	const float R = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats];
-	const float G = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 1];
-	const float B = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 2];
-	const float Width = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 3];
+	FGPULineArray& Line = LineMap[LineId];
+	const float R = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats];
+	const float G = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 1];
+	const float B = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 2];
+	const float Width = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 3];
 
 	const FIntPoint InitialTextureMarker = CurrentTextureMarker;
 	// Check if it's the last line:
 
-	GPULineIndices& Indices = Line.Last();	
-	const int32 PointTextureIndex = Indices.Value;
-	FVector4& PreviousLastPoint = LinearLineData[Indices.Value];
+	FGPULineIndices& Indices = Line.IndexArray.Last();	
+	const int32 PointTextureIndex = Indices.TextureIndex;
+	FVector4& PreviousLastPoint = LinearLineData[Indices.TextureIndex];
 	PreviousLastPoint.W = 1.0; // This isn't the line end anymore.
 
 	if (LineId == NextFreeId - 1)
@@ -906,9 +927,9 @@ bool UGPUInstancedLineComponent::AddPoints(int32 LineId, const TArray<FVector>&
 
 			// Update the latest dummy entry to point to the actual segment.
 			if (PointIndex == 0)
-				Line.Last().Key = InstanceId;
+				Line.IndexArray.Last().InstanceIndex = InstanceId;
 			else
-				Line.Add(TPair<int32, int32>{InstanceId, LinearLineData.Num() - 1 + PointIndex});
+				Line.IndexArray.Add({InstanceId, LinearLineData.Num() - 1 + PointIndex});
 			CurrentTextureIndex++;
 			MoveTextureMarker();
 		}
@@ -917,7 +938,7 @@ bool UGPUInstancedLineComponent::AddPoints(int32 LineId, const TArray<FVector>&
 		LinearLineData.Last().W = -1;
 		
 		// Add a new dummy entry for the last point
-		Line.Add(GPULineIndices{ -1, LinearLineData.Num() - 1 });
+		Line.IndexArray.Add({ -1, LinearLineData.Num() - 1 });
 
 		CurrentTextureIndex++;
 		MoveTextureMarker();
@@ -949,19 +970,19 @@ bool UGPUInstancedLineComponent::AddPoints(int32 LineId, const TArray<FVector>&
 	// This is slightly more complicated as all the indices after the added points need to be adjusted.
 	// Additionally, the points needs to be inserted into the texture, shifting the whole thing. 
 
-	const int32 NewPointTextureIndex = Indices.Value + 1;
+	const int32 NewPointTextureIndex = Indices.TextureIndex + 1;
 
 	// Update all LineMap Indices that have a texture index larger than the newly inserted point. Todo: Make more efficient, maybe remove map and swap to array:
-	for (TPair<int32, GPULineArray>& Pair : LineMap)
+	for (TPair<int32, FGPULineArray>& Pair : LineMap)
 	{
-		GPULineArray& LineArray = Pair.Value;
-		if (LineArray[0].Value >= NewPointTextureIndex)
+		FGPULineArray& LineArray = Pair.Value;
+		if (LineArray.IndexArray[0].TextureIndex >= NewPointTextureIndex)
 		{
 			// Need to increase all indices by 1 and adjust the custom data
-			for (int32 i = 0; i < LineArray.Num(); ++i)
+			for (int32 i = 0; i < LineArray.IndexArray.Num(); ++i)
 			{
-				LineArray[i].Value += Points.Num();
-				SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);
+				LineArray.IndexArray[i].TextureIndex += Points.Num();
+				SetCustomDataValue(LineArray.IndexArray[i].InstanceIndex, 4, LineArray.IndexArray[i].TextureIndex, false);
 			}
 		}
 	}
@@ -978,10 +999,10 @@ bool UGPUInstancedLineComponent::AddPoints(int32 LineId, const TArray<FVector>&
 
 		// Update the latest dummy entry to point to the actual segment.
 		if (PointIndex == 0)
-			Line.Last().Key = InstanceId;
+			Line.IndexArray.Last().InstanceIndex = InstanceId;
 		else
 		{
-			Line.Add(TPair<int32, int32>{InstanceId, NewPointTextureIndex + PointIndex - 1});
+			Line.IndexArray.Add({InstanceId, NewPointTextureIndex + PointIndex - 1});
 			CurrentTextureIndex++;
 			MoveTextureMarker();			
 		}
@@ -994,7 +1015,7 @@ bool UGPUInstancedLineComponent::AddPoints(int32 LineId, const TArray<FVector>&
 	LinearLineData.Insert(TextureData, NewPointTextureIndex);
 	
 	// Add it to the LineMap - this is the new dummy segment because we add it at the end of the line
-	Line.Add(GPULineIndices{ -1, NewPointTextureIndex + Points.Num() - 1 });
+	Line.IndexArray.Add({ -1, NewPointTextureIndex + Points.Num() - 1 });
 	//SetCustomDataValue(InstanceId, 4, NewPointTextureIndex, true);
 
 	CurrentTextureIndex++;
@@ -1011,18 +1032,18 @@ bool UGPUInstancedLineComponent::InsertPoints(int32 LineId, int32 SegmentId, con
 {
 	TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::InsertPoint"))
 
-	GPULineArray& Line = LineMap[LineId];
+	FGPULineArray& Line = LineMap[LineId];
 
-	if (SegmentId == Line.Num())
+	if (SegmentId == Line.IndexArray.Num())
 	{
 		return AddPoints(LineId, Points);
 	}
-	const float R = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats];
-	const float G = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 1];
-	const float B = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 2];
-	const float Width = PerInstanceSMCustomData[Line[0].Key * NumCustomDataFloats + 3];
+	const float R = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats];
+	const float G = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 1];
+	const float B = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 2];
+	const float Width = PerInstanceSMCustomData[Line.IndexArray[0].InstanceIndex * NumCustomDataFloats + 3];
 
-	const int32 LinearDataIndex = Line[SegmentId].Value;
+	const int32 LinearDataIndex = Line.IndexArray[SegmentId].TextureIndex;
 	LinearLineData.Insert(TArray<FVector4>(Points), LinearDataIndex);
 	if (SegmentId == 0)
 	{
@@ -1040,30 +1061,30 @@ bool UGPUInstancedLineComponent::InsertPoints(int32 LineId, int32 SegmentId, con
 		SetCustomDataValue(InstanceId, 2, B, false);
 		SetCustomDataValue(InstanceId, 3, Width, false);
 		
-		Line.Insert(GPULineIndices{ InstanceId, LinearDataIndex + PointIndex }, SegmentId + PointIndex);
+		Line.IndexArray.Insert({ InstanceId, LinearDataIndex + PointIndex }, SegmentId + PointIndex);
 		SetCustomDataValue(InstanceId, 4, LinearDataIndex + PointIndex, false);
 		CurrentTextureIndex++;
 		MoveTextureMarker();
 	}
 
 	// Update the rest of the line
-	for (int32 i = SegmentId + Points.Num(); i < Line.Num(); ++i)
+	for (int32 i = SegmentId + Points.Num(); i < Line.IndexArray.Num(); ++i)
 	{
-		Line[i].Value += Points.Num();
-		SetCustomDataValue(Line[i].Key, 4, Line[i].Value);
+		Line.IndexArray[i].TextureIndex += Points.Num();
+		SetCustomDataValue(Line.IndexArray[i].InstanceIndex, 4, Line.IndexArray[i].TextureIndex);
 	}
 
 	// Update all following lines
-	for (TPair<int32, GPULineArray>& Pair : LineMap)
+	for (TPair<int32, FGPULineArray>& Pair : LineMap)
 	{
-		GPULineArray& LineArray = Pair.Value;
-		if (LineArray[0].Value > LinearDataIndex)
+		FGPULineArray& LineArray = Pair.Value;
+		if (LineArray.IndexArray[0].TextureIndex > LinearDataIndex)
 		{
 			// Need to increase all indices by 1 and adjust the custom data
-			for (int32 i = 0; i < LineArray.Num(); ++i)
+			for (int32 i = 0; i < LineArray.IndexArray.Num(); ++i)
 			{
-				LineArray[i].Value += Points.Num();
-				SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);
+				LineArray.IndexArray[i].TextureIndex += Points.Num();
+				SetCustomDataValue(LineArray.IndexArray[i].InstanceIndex, 4, LineArray.IndexArray[i].TextureIndex, false);
 			}
 		}
 	}
@@ -1081,9 +1102,9 @@ bool UGPUInstancedLineComponent::UpdateLine(int32 LineId, TArray<FVector>& Point
 {
 	TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::UpdateLine"))
 
-	const GPULineArray& Line = LineMap[LineId];
+	const FGPULineArray& Line = LineMap[LineId];
 
-	if(Line.Num() != Points.Num())
+	if(Line.IndexArray.Num() != Points.Num())
 	{
 		return false;
 	}
@@ -1091,7 +1112,7 @@ bool UGPUInstancedLineComponent::UpdateLine(int32 LineId, TArray<FVector>& Point
 	TArray<FVector4>* TextureData = new TArray<FVector4>(MoveTemp(Points));
 	TextureData->Last().W = -1;
 	(*TextureData)[0].W = 0;
-	const int32 TextureIndex = Line[0].Value;
+	const int32 TextureIndex = Line.IndexArray[0].TextureIndex;
 	const FIntPoint StartIndex(TextureIndex % TextureWidth, TextureIndex / TextureWidth);
 	
 	FMemory::Memcpy(LinearLineData.GetData() + TextureIndex, TextureData->GetData(), TextureData->Num() * sizeof(FVector4));
@@ -1179,16 +1200,16 @@ bool UGPUInstancedLineComponent::DrawLinesDirectly(int32 LineIdStart, TArray<FVe
 bool UGPUInstancedLineComponent::UpdatePoint(int32 LineId, int32 PointId, const FVector& Point)
 {
 	// Should check for validity
-	const GPULineIndices& PointIndices = LineMap[LineId][PointId];
+	const FGPULineIndices& PointIndices = LineMap[LineId].IndexArray[PointId];
 
 	// Only need to update the linear data - don't overwrite W as the line start/end doesn't change
-	LinearLineData[PointIndices.Value].X = Point.X;
-	LinearLineData[PointIndices.Value].Y = Point.Y;
-	LinearLineData[PointIndices.Value].Z = Point.Z;
+	LinearLineData[PointIndices.TextureIndex].X = Point.X;
+	LinearLineData[PointIndices.TextureIndex].Y = Point.Y;
+	LinearLineData[PointIndices.TextureIndex].Z = Point.Z;
 
-	const int32 InstanceId = (PointIndices.Key != -1) ? PointIndices.Key : LineMap[LineId][PointId - 1].Key;
+	const int32 InstanceId = (PointIndices.InstanceIndex != -1) ? PointIndices.InstanceIndex : LineMap[LineId].IndexArray[PointId - 1].InstanceIndex;
 
-	const int32 TextureIndex = PointIndices.Value;
+	const int32 TextureIndex = PointIndices.TextureIndex;
 	//const int32 Y = PerInstanceSMCustomData[InstanceId * NumCustomDataFloats + 5];
 	const int32 X = TextureIndex % TextureWidth;
 	const int32 Y = TextureIndex / TextureWidth;
@@ -1205,7 +1226,7 @@ bool UGPUInstancedLineComponent::UpdatePoint(int32 LineId, int32 PointId, const
 
 
 	// Copy for now - no need to do that 
-	TArray<FVector4>* TextureData = new TArray<FVector4>{ LinearLineData[PointIndices.Value] };
+	TArray<FVector4>* TextureData = new TArray<FVector4>{ LinearLineData[PointIndices.TextureIndex] };
 
 
 	PositionTexture->UpdateTextureRegions(0, 1, Region, TextureWidth * sizeof(FVector4), sizeof(FVector4), (uint8*)TextureData->GetData(),
@@ -1224,31 +1245,31 @@ bool UGPUInstancedLineComponent::UpdatePoints(int32 LineId, int32 StartingPointI
 {
 	TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::UpdatePoints"))
 
-	const GPULineArray& Line = LineMap[LineId];
+	const FGPULineArray& Line = LineMap[LineId];
 
-	if (Line.Num() < Points.Num() || StartingPointId + Points.Num() > Line.Num())
+	if (Line.IndexArray.Num() < Points.Num() || StartingPointId + Points.Num() > Line.IndexArray.Num())
 	{
 		return false;
 	}
-	if(Line.Num() == Points.Num() && StartingPointId == 0)
+	if(Line.IndexArray.Num() == Points.Num() && StartingPointId == 0)
 	{
 		return UpdateLine(LineId, Points);
 	}
 
 	// Should check for validity
-	const GPULineIndices& FirstPointIndices = LineMap[LineId][StartingPointId];
+	const FGPULineIndices& FirstPointIndices = LineMap[LineId].IndexArray[StartingPointId];
 
 	TArray<FVector4>* TextureData = new TArray<FVector4>(MoveTemp(Points));
 	if(StartingPointId == 0)
 	{
 		(*TextureData)[0].W = 0;
 	}
-	if (StartingPointId + Points.Num() == Line.Num())
+	if (StartingPointId + Points.Num() == Line.IndexArray.Num())
 	{
 		TextureData->Last().W = -1;
 	}
 	
-	const int32 StartTextureIndex = Line[StartingPointId].Value;
+	const int32 StartTextureIndex = Line.IndexArray[StartingPointId].TextureIndex;
 	const FIntPoint StartIndex(StartTextureIndex % TextureWidth, StartTextureIndex / TextureWidth);
 
 	FMemory::Memcpy(LinearLineData.GetData() + StartTextureIndex, TextureData->GetData(), TextureData->Num() * sizeof(FVector4));
@@ -1270,20 +1291,20 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
 {
 	TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::RemoveLine"))
 
-	const GPULineArray& Line = LineMap[LineId];
-	const int32 LineLength = Line.Num();
-	const int32 LineTextureIndex = Line[0].Value;
+	const FGPULineArray& Line = LineMap[LineId];
+	const int32 LineLength = Line.IndexArray.Num();
+	const int32 LineTextureIndex = Line.IndexArray[0].TextureIndex;
 
 	// Because ISM are so great, they reshuffle id's on removal....
 	// This means we can't just remove consecutive ids, but need to actually re-calculate them EVERY SINGLE TIME
 	// As instances of a line aren't guaranteed to be in order, collect and sort the indices first, then start top down.
 	//
 	TArray<int32> InstancesToRemove;
-	InstancesToRemove.Reserve(Line.Num());
+	InstancesToRemove.Reserve(Line.IndexArray.Num());
 	
-	for(int32 PointIndex = 0; PointIndex < Line.Num() - 1; PointIndex++)
+	for(int32 PointIndex = 0; PointIndex < Line.IndexArray.Num() - 1; PointIndex++)
 	{
-		InstancesToRemove.Add(Line[PointIndex].Key);
+		InstancesToRemove.Add(Line.IndexArray[PointIndex].InstanceIndex);
 	}
 	InstancesToRemove.Sort();
 
@@ -1298,12 +1319,12 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
 	LineMap.Remove(LineId);
 	
 	// Update all following lines
-	for (TPair<int32, GPULineArray>& Pair : LineMap)
+	for (TPair<int32, FGPULineArray>& Pair : LineMap)
 	{
-		GPULineArray& LineArray = Pair.Value;
-		for (int32 i = 0; i < LineArray.Num(); ++i)
+		FGPULineArray& LineArray = Pair.Value;
+		for (int32 i = 0; i < LineArray.IndexArray.Num(); ++i)
 		{
-			if (LineArray[i].Key >= InstancesToRemove[0])
+			if (LineArray.IndexArray[i].InstanceIndex >= InstancesToRemove[0])
 			{
 				// Apparently unreal also shuffles the instance indices, this might bite us later on
 
@@ -1311,17 +1332,17 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
 
 				for(int32 Index = InstancesToRemove.Num(); Index > 0; --Index)
 				{
-					if (LineArray[i].Key >= InstancesToRemove[Index - 1])
+					if (LineArray.IndexArray[i].InstanceIndex >= InstancesToRemove[Index - 1])
 					{
-						LineArray[i].Key -= Index;
+						LineArray.IndexArray[i].InstanceIndex -= Index;
 						break;
 					}
 				}								
 			}
-			if (LineArray[0].Value >= LineTextureIndex)
+			if (LineArray.IndexArray[0].TextureIndex >= LineTextureIndex)
 			{
-				LineArray[i].Value -= LineLength;
-				SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);
+				LineArray.IndexArray[i].TextureIndex -= LineLength;
+				SetCustomDataValue(LineArray.IndexArray[i].InstanceIndex, 4, LineArray.IndexArray[i].TextureIndex, false);
 			}
 		}
 	}
@@ -1364,10 +1385,10 @@ bool UGPUInstancedLineComponent::RemovePoint(int32 LineId, int32 PointId)
 {
 	TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::RemovePoint"))
 
-	GPULineArray& Line = LineMap[LineId];
-	const GPULineIndices& Indices = Line[PointId];
-	const int32 LineTextureIndex = Indices.Value;
-	int32 RemovedInstanceId = Indices.Key;
+	FGPULineArray& Line = LineMap[LineId];
+	const FGPULineIndices& Indices = Line.IndexArray[PointId];
+	const int32 LineTextureIndex = Indices.TextureIndex;
+	int32 RemovedInstanceId = Indices.InstanceIndex;
 
 	if (PointId == 0)
 	{
@@ -1377,42 +1398,42 @@ bool UGPUInstancedLineComponent::RemovePoint(int32 LineId, int32 PointId)
 	LinearLineData.RemoveAt(LineTextureIndex);
 
 	// Last point is special
-	if(PointId == Line.Num() - 1)
+	if(PointId == Line.IndexArray.Num() - 1)
 	{
-		LinearLineData[Line[PointId - 1].Value].W = -1;
-		RemovedInstanceId = Line[PointId - 1].Key;
-		RemoveInstance(Line[PointId - 1].Key);
-		Line[PointId - 1].Key = -1;
+		LinearLineData[Line.IndexArray[PointId - 1].TextureIndex].W = -1;
+		RemovedInstanceId = Line.IndexArray[PointId - 1].InstanceIndex;
+		RemoveInstance(Line.IndexArray[PointId - 1].InstanceIndex);
+		Line.IndexArray[PointId - 1].InstanceIndex = -1;
 	}
 	else
 	{
 		// Update the following segments in this line:
-		for (int32 i = PointId + 1; i < Line.Num(); ++i)
+		for (int32 i = PointId + 1; i < Line.IndexArray.Num(); ++i)
 		{
-			Line[i].Value -= 1;
-			SetCustomDataValue(Line[i].Key, 4, Line[i].Value, false);
+			Line.IndexArray[i].TextureIndex -= 1;
+			SetCustomDataValue(Line.IndexArray[i].InstanceIndex, 4, Line.IndexArray[i].TextureIndex, false);
 		}
 		MarkRenderStateDirty();
 
 		RemoveInstance(RemovedInstanceId);
 	}
-	Line.RemoveAt(PointId);
+	Line.IndexArray.RemoveAt(PointId);
 
 	// Update all following lines
-	for (TPair<int32, GPULineArray>& Pair : LineMap)
+	for (TPair<int32, FGPULineArray>& Pair : LineMap)
 	{
-		GPULineArray& LineArray = Pair.Value;
-		for (int32 i = 0; i < LineArray.Num(); ++i)
+		FGPULineArray& LineArray = Pair.Value;
+		for (int32 i = 0; i < LineArray.IndexArray.Num(); ++i)
 		{
-			if (LineArray[i].Key >= RemovedInstanceId)
+			if (LineArray.IndexArray[i].InstanceIndex >= RemovedInstanceId)
 			{
 				// Apparently unreal also shuffles the instance indices, this might bite us later on
-				LineArray[i].Key -= 1;
+				LineArray.IndexArray[i].InstanceIndex -= 1;
 			}
-			if (LineArray[0].Value > LineTextureIndex)
+			if (LineArray.IndexArray[0].TextureIndex > LineTextureIndex)
 			{
-				LineArray[i].Value -= 1;
-				SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);
+				LineArray.IndexArray[i].TextureIndex -= 1;
+				SetCustomDataValue(LineArray.IndexArray[i].InstanceIndex, 4, LineArray.IndexArray[i].TextureIndex, false);
 			}
 		}
 	}
@@ -1439,11 +1460,11 @@ bool UGPUInstancedLineComponent::RemovePoints(int32 LineId, int32 StartingPointI
 
 bool UGPUInstancedLineComponent::SetLineColor(int32 LineId, const FLinearColor& Color)
 {
-	const GPULineArray& Line = LineMap[LineId];
+	const FGPULineArray& Line = LineMap[LineId];
 
-	for (const GPULineIndices& LineIndices: Line)
+	for (const FGPULineIndices& LineIndices: Line.IndexArray)
 	{
-		const int32 InstanceId = LineIndices.Key;
+		const int32 InstanceId = LineIndices.InstanceIndex;
 		if (InstanceId >= 0)
 		{
 			SetCustomDataValue(InstanceId, 0, Color.R, false);
@@ -1459,7 +1480,7 @@ bool UGPUInstancedLineComponent::SetSegmentColor(int32 LineId, int32 SegmentId,
 {
 	// Get Instance Id:
 
-	const int32 InstanceId = LineMap[LineId][SegmentId].Key;
+	const int32 InstanceId = LineMap[LineId].IndexArray[SegmentId].InstanceIndex;
 
 	SetCustomDataValue(InstanceId, 0, Color.R, false);
 	SetCustomDataValue(InstanceId, 1, Color.G, false);
@@ -1470,11 +1491,11 @@ bool UGPUInstancedLineComponent::SetSegmentColor(int32 LineId, int32 SegmentId,
 
 bool UGPUInstancedLineComponent::SetLineWidth(int32 LineId, float Width)
 {
-	const GPULineArray& Line = LineMap[LineId];
+	const FGPULineArray& Line = LineMap[LineId];
 
-	for (const GPULineIndices& LineIndices : Line)
+	for (const FGPULineIndices& LineIndices : Line.IndexArray)
 	{
-		const int32 InstanceId = LineIndices.Key;
+		const int32 InstanceId = LineIndices.InstanceIndex;
 		if (InstanceId >= 0)
 		{
 			SetCustomDataValue(InstanceId, 3, Width, false);
@@ -1486,9 +1507,9 @@ bool UGPUInstancedLineComponent::SetLineWidth(int32 LineId, float Width)
 
 bool UGPUInstancedLineComponent::SetSegmentWidth(int32 LineId, int32 SegmentId, float Width)
 {
-	const int32 InstanceId = LineMap[LineId][SegmentId].Key;
+	const int32 InstanceId = LineMap[LineId].IndexArray[SegmentId].InstanceIndex;
 
 	SetCustomDataValue(InstanceId, 3, Width, false);
 	return true;
 }
-//#pragma optimize("", on)
+#pragma optimize("", on)
diff --git a/Source/InstancedMeshLineRendering/Public/GPUInstancedLineComponent.h b/Source/InstancedMeshLineRendering/Public/GPUInstancedLineComponent.h
index d3e9bda0ac146af29879f6c2093954f6835fccf0..c9e7e5a4ba6a417fabd1a1281c99891b09a9e989 100644
--- a/Source/InstancedMeshLineRendering/Public/GPUInstancedLineComponent.h
+++ b/Source/InstancedMeshLineRendering/Public/GPUInstancedLineComponent.h
@@ -13,13 +13,20 @@
 //typedef TPair<FVector, TTuple<int32, int32, int32>>	GPULineSegment;
 
 // Pair of InstanceId and LinearData index.
-typedef TPair<int32, int32> GPULineIndices;
+//
+
+
 
 // LineArray that contains indices into the instance list and the linear data.
+
+typedef TPair<int32, int32> GPULineIndices;
+
 typedef TArray<GPULineIndices>		GPULineArray;
 
 // Maps a LineId to a LineArray. 
-typedef TMap<int32, GPULineArray>	GPULinesMap; 
+typedef TMap<int32, GPULineArray>	GPULinesMap;
+
+
 
 USTRUCT(BlueprintType)
 struct FEditorPoint
@@ -55,6 +62,7 @@ struct FEditorLineData
 	UPROPERTY(EditAnywhere)
 	FColor Color;
 
+	UPROPERTY()
 	int32 RespectiveLineId = -1;
 	
 	FEditorLineData()
@@ -74,12 +82,59 @@ struct FEditorLineData
 	}
 };
 
+USTRUCT()
+struct FGPULineIndices
+{
+	GENERATED_USTRUCT_BODY()
+
+	UPROPERTY()
+	int32 InstanceIndex;
+
+	UPROPERTY()
+	int32 TextureIndex;
+
+	FGPULineIndices() = default;
+
+	FGPULineIndices(int32 InstanceIndex, int32 TextureIndex)
+		: InstanceIndex(InstanceIndex), TextureIndex(TextureIndex) {}
+};
+
+USTRUCT()
+struct FGPULineArray
+{
+	GENERATED_USTRUCT_BODY()
+
+	UPROPERTY()
+	TArray<FGPULineIndices> IndexArray;
+};
 
-UCLASS(Blueprintable, BlueprintType, meta = (BlueprintSpawnableComponent), HideCategories=("Instances", "Object", "LOD", "Physics", "Activation", "Materials", "Cooking", "Sockets", "Collision", "Mobile", "HLOD"))
+UCLASS(Blueprintable, BlueprintType, meta = (BlueprintSpawnableComponent), HideCategories=(Object, LOD, Physics, Activation, Materials, "Cooking", "Sockets", "Collision", "Mobile", "HLOD"))
 class INSTANCEDMESHLINERENDERING_API UGPUInstancedLineComponent : public UInstancedStaticMeshComponent
 {
 	GENERATED_BODY()
 
+public:
+
+	UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer);
+	~UGPUInstancedLineComponent();
+
+	virtual void BeginPlay() override;
+
+	virtual void PostInitProperties() override;
+#if WITH_EDITOR
+	virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override;
+	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; // need this for the widget as for some godforsaken reason the Chain event doesn't fire...
+	// This is ABSURDLY hacky
+	virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) override;
+
+#endif
+
+	virtual void PostLoad() override;
+	virtual void OnComponentCreated() override;
+	virtual void BeginDestroy() override;
+
+	virtual void Serialize(FArchive& Ar) override;
+	
 private:
 
 	void MoveTextureMarker()
@@ -97,48 +152,13 @@ private:
 
 	void Init();
 
-	void RegisterSerializedEditorLines();
+	//void RegisterSerializedEditorLines();
 
 	void UpdateAllEditorLines();
 
 	FUpdateTextureRegion2D* CalculateTextureRegions(const FIntPoint& StartIndex, int32 NumberOfPoints, int32& NumberOfRegionsOut);
 
-	GPULinesMap LineMap;
-
-	TArray<FVector4> LinearLineData;
-
-	// Array that keeps track of editor lines. This is ONLY needed because the array can be cleared by a simple stupid button press in the
-	// details panel, circumventing the PostEditChangeChainProperty function by clearing the array first. The change callback gets called, but
-	// as the EditorLines array has already been cleared, it's not possible to backtrack the removed lines.
-	TArray<int32> EditorLineIds;
-
-	int32 NextFreeId = 0;
-	int32 CurrentTextureIndex;
-	FIntPoint CurrentTextureMarker;
-
-	bool bIsInitialized = false;
-
-protected:
-	virtual void BeginPlay() override;
-
-	virtual void PostInitProperties() override;
-#if WITH_EDITOR
-	virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override;
-	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; // need this for the widget as for some godforsaken reason the Chain event doesn't fire...
-	// This is ABSURDLY hacky
-	virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) override;
-
-#endif
-
-	virtual void PostLoad() override;
-	virtual void OnComponentCreated() override;
-	virtual void BeginDestroy() override;	
-
 public:
-
-	UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer);
-	~UGPUInstancedLineComponent();
-
 	// todo
 	void ReleaseData();
 
@@ -423,7 +443,7 @@ public:
 	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Components|InstancedLineComponent")
 	int32 GetNumberOfPointsInLine(int32 LineId) const
 	{
-		return LineMap[LineId].Num();
+		return LineMap[LineId].IndexArray.Num();
 	}
 
 	UPROPERTY(BlueprintReadWrite, EditAnywhere)
@@ -438,10 +458,34 @@ public:
 	UPROPERTY(BlueprintReadOnly, EditAnywhere)
 	int32 TextureHeight;
 
-	UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
+	UPROPERTY(transient)
 	UMaterialInstanceDynamic* DynamicLineMaterial;
 
 	UPROPERTY(EditAnywhere, DisplayName = "Lines", meta = (MakeEditWidget = true, EditFixedOrder))
 	TArray<FEditorLineData> EditorLines;
 
+private:
+
+	UPROPERTY()
+	TMap<int32, FGPULineArray> LineMap;
+	
+	UPROPERTY()
+	TArray<FVector4> LinearLineData;
+
+	// Array that keeps track of editor lines. This is ONLY needed because the array can be cleared by a simple stupid button press in the
+	// details panel, circumventing the PostEditChangeChainProperty function by clearing the array first. The change callback gets called, but
+	// as the EditorLines array has already been cleared, it's not possible to backtrack the removed lines.
+	UPROPERTY()
+	TArray<int32> EditorLineIds;
+
+	UPROPERTY()
+	int32 NextFreeId;
+
+	UPROPERTY()
+	int32 CurrentTextureIndex;
+
+	UPROPERTY()
+	FIntPoint CurrentTextureMarker;
+
+	bool bIsInitialized = false;
 };
\ No newline at end of file