Hi all,
I’ve a problem with nested inheritance of the same class with child components.
Here is my classes hierarchy:
- ConstrainedComponent class inherits from UStaticMeshComponent class.
- Lever Class inherits from ConstrainedComponent class.
- FrontPanel Class inherits from ConstrainedComponent class, and contains a Lever Property.
The problem is that when instancing a Front Panel in game, after the BeginPlay (not before) the FrontPanel’s Constraint is moved in a wrong position (seems to accumulate parent’s positions and rotation set in the constructor).
The problem is related only when nested in this case, and can be solved by giving a different name to the Constraint Component using a progressive static int in the ConstrainedComponent Constructor. the solution is shown at the end of this post.
Here is a sample code:
======== ConstrainedComponent.h ===========
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ENELTRAINING_API UConstrainedComponent : public UStaticMeshComponent, public IGrabbableComponent
{
GENERATED_BODY()
public:
UConstrainedComponent();
...
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "ConstrainedComponent")
UPhysicsConstraintComponent* Constraint;
...}
======== ConstrainedComponent.cpp ===========
UConstrainedComponent::UConstrainedComponent() : Super()
{
...
Constraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("Constraint"));
Constraint->AttachParent = this;
...
}
======== RU_Lever.h ===========
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class ENELTRAINING_API URU_Lever : public UConstrainedComponent
{
....
}
======== RU_FrontPanel.h ===========
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class ENELTRAINING_API URU_FrontPanel : public UConstrainedComponent
{
...
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FrontPanel")
URU_Lever* Lever;
...
}
Proposed Solution in ConstrainedComponent.h constructor:
struct FConstructorStatics
{
int InstanceCount;
FConstructorStatics(): InstanceCount(0) {}
};
static FConstructorStatics ConstructorStatics;
++ConstructorStatics.InstanceCount;
...
FString ConstraintName = FString::Printf(TEXT("Constraint%i"), ConstructorStatics.InstanceCount);
Constraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(*ConstraintName);
...
Is correct to use the CreateDefaultSubobject call in the constructor instead of the NewObject?
Is the proposed solution correct or is there a more elegant way to make it work?
Thanks