Hey there! I am referring to clamping.
But, I want to set such a clamp to be applied on a given Actor’s world scale anytime that Actor gets resized, even if that Actor is resized indirectly via a component attachment. Even if the Actor is attached to a parent component, and that parent component is resized (scaled), I want the Actor to clamp itself to stay within a certain world scale, even while the parent component continues to change scale.
I finally found a solution to this by modifying the engine source code.
I modified SceneComponent.h
to allow a function to be provided to clamp or bound the world scale of a given SceneComponent
.
In SceneComponent.h
I added a public member:
/** Assign a lambda to this function to bound the world scale of the
* component based on custom logic. Before the scale of the component
* gets committed, this function is run to return the final scale which
* will actually be applied to the component.
*
* @param desiredWorldScale the world scale that the component is about
* to be set to prior to this function possibly bounding it
*
* @return the final world scale vector the component should be set to.
*
* @note This function will be called when the scale of the component is
* set directly OR when the component is a child of another
* component that is being scaled.
*/
std::function<FVector(FVector)> BoundWorldScale;
Then in SceneComponent.cpp
I use this function to bound the World Scale of component before it gets set (either directly or via a parent attachment). I added this modification to SceneComponent::UpdateComponentToWorldWithParent
:
void USceneComponent::UpdateComponentToWorldWithParent(...)
{
// ...
NewTransform = CalcNewComponentToWorld(RelativeTransform, Parent, SocketName);
// I added this bit to bound the newly calculated transform
if (BoundWorldScale)
NewTransform.SetScale3D (BoundWorldScale (NewTransform.GetScale3D()));
// ...
}
Now that the engine code is modified, in whatever actor I want, I can easily bound the world scale to my liking:
class AMyActor : public AActor
{
AMyActor()
{
RootComponent = CreateDefaultSubobject<USceneComponent> (TEXT ("ROOT"));
// Clamp this actor's world scale from half scale (0.5) to full scale (1.0)
RootComponent->BoundWorldScale = [](FVector DesiredWorldScale)
{
return ClampVector (DesiredWorldScale, FVector (0.5f), FVector (1.0f));
}
}
};