I’ve done this a while ago, IIRC you need the following classes, the process is a bit involved:
-UYourSplineComponent, deriving from USplineComponent
The component which will actually be on the actors in game
-UYourSplineMetadata, deriving from USplineMetadata
This holds the actual data for the points, you need to store this manually in UYourSplineComponent or the actor owning that component (stored as a UPROPERTY so it isn’t GC’d, might need to be instanced)
(If stored on the component you need to mess about with GetComponentInstanceData / FSceneComponentInstanceData as component data might get cleared for BP classes when they get reconstructed in editor)
USplineComponent::GetSplinePointsMetadata should be overridden to return UYourSplineMetadata
-FYourSplineMetadataDetails deriving from ISplineMetadataDetails
This class handles the UI for the custom metadata on each point
-UYourSplineMetadataDetailsFactory, deriving from USplineMetadataDetailsFactoryBase
Override GetMetadataClass() to return the class of UYourSplineMetadata
Override Create() to return the type of FYouSplineMetadataDetails
“Where do I tell the engine to use my own USplineMetadataDetailsFactoryBase?”
You don’t tell it explicitly, rather in the first code you posted (where the crash is) it is looping over all classes deriving from USplineMetadataDetailsFactoryBase, and the class returned from SplineComp->GetSplinePointsMetadata() should match the class returned from Factory->GetMetadataClass() (i.e. UYourSplineMetadata)
They really should have made all this a bit easier, and auto-generate the UI / metadata etc using their PROPERTY macros, but this was probably added as an afterthought.
If you’re still stuck I would advise to follow the engine example from WaterSpline (used for rivers etc) (EDIT: whoops just saw you said you were doing this already, must have missed a step somewhere)