The latest Spine Runtime for UE4 still has these two issues.
1: Memory Leak in SpineSlateMaterialBrush
struct SpineSlateMaterialBrush : public FSlateBrush {
SpineSlateMaterialBrush(class UMaterialInterface &InMaterial, const FVector2D &InImageSize)
: FSlateBrush(ESlateBrushDrawType::Image, FName(TEXT("None")), FMargin(0), ESlateBrushTileType::NoTile, ESlateBrushImageType::FullColor, InImageSize, FLinearColor::White, &InMaterial) {
// Workaround for https://github.com/EsotericSoftware/spine-runtimes/issues/2006
FString brushName = TEXT("spineslatebrush");
brushName.AppendInt(brushNameId++);
ResourceName = FName(brushName);
// The above code causes an infinite increase in FName entries, leading to uncontrolled memory growth in UE,
// eventually causing an out-of-memory crash.
// No fix code is provided here as my solution is temporary.
// Just a complaint—if you don't understand UE4, don't mess around with the code!
}
};
2: Crash due to Wild Pointer When Switching Spine Animations
File: SpineSkeletonAnimationComponent.cpp
void callback(AnimationState *state, spine::EventType type, TrackEntry *entry, Event *event) {
USpineSkeletonAnimationComponent *component = (USpineSkeletonAnimationComponent *)
state->getRendererObject();
if (entry->getRendererObject()) {
UTrackEntry *uEntry = (UTrackEntry *) entry->getRendererObject();
// Warning: `uEntry` may be a wild pointer!
......
}
}
Root Cause:
UTrackEntry and TrackEntry hold mutual pointer references. However, since UTrackEntry is managed by UE's garbage collection system, it is not immediately destroyed when no longer used. This leads to scenarios where TrackEntry holds a dangling pointer to UTrackEntry, causing a crash when accessed.
Impact:
This crash can occur in both Widget-based animations and Scene-based animations.
Fix Approach:
When TrackEntry is deleted, it must remove the reference to UTrackEntry.
When UTrackEntry is no longer needed (note: not deleted immediately), it must remove the reference to TrackEntry.