SetRelativeLocation/Transform in actor constructor not working?

So, this seems really basic. I’m moving some actor construction stuff from blueprint into code. I have a component which needs to have an offset applied to it from its parent.

In the actor constructor, I have:
RootComponent = CreateDefaultSubobject(TEXT(“Root”));
Hand_Left = CreateDefaultSubobject(TEXT(“Hand_Left”));
Hand_Left->SetupAttachment(RootComponent);
Hand_Left->SetRelativeLocation(FVector(8.0f, 0.0f, 0,0f));

(Hand_Left is just a USceneComponent for all applicable purposes.)

However, SetRelativeLocation doesn’t work. Neither does SetRelativeTransform, or setting the RElativeLocation member directly. Hand_Left, in the editor and game, is still at the same location as root component. The Location property in the actor in blueprint (more precisely, a BP version of the actor which inherits from the code version) is set to relative but shows a location of 0,0,0. There is no little yellow “reset” arrow to indicate that the value trying to be set in the constructor is being overridden.

It works if I do it in PostInitializeComponents() in that the component is in the right spot. However, the “location” value shown in the BP class in the editor breaks: it shows 0,0,0 instead of the actual offset, and editing it has no effect. (You can change the value, but the component doesn’t move in the viewport.)

According to the coding 101 tutorial (https://docs.unrealengine.com/latest/INT/Programming/Tutorials/Components/1/ see step 5’s code sample), I am supposed to be able to set the relative location of the component in the actor’s constructor.

Is this just broken? Or is there a new way to do this? It seems like awfully fundamental functionality to break unnoticed.

I’m seeing the exact same behavior. What is the proper way to set the transform of a component in the parent’s constructor?

If someone else stumbles upon this, this is working as intended. Instance values like that are saved on the blueprint, and are not overwritten on recompilation. Otherwise, every small change to the C++ code would wipe out your modifications in the blueprint. Existing blueprints only really update when objects are added or removed from the class.

You have three options to get it to “update”:

  1. Manually update values in the blueprint editor. This is ideal if you have just a few changes to make.
  2. Delete the blueprint and recreate it. Those instance values will initialize based on the constructor. Obviously, any changes you made to the blueprint (component values, event graph, etc.) would be lost.
  3. The third option is a little less destructive; you can remove just the component you want to update from the object (comment out the code creating and attaching the component), compile, add the component back, compile, and when the component is added back to the blueprint, it will initialize its values based on the constructor. Only changes made to that component on the blueprint would be lost. I think references to that component in the blueprint event graph, functions, etc. will persist, but you might want to test that before trying this. This is really the best option if you need to update some change across many blueprints based on that class.

Some relevant discussion here.

Edit: Hmm, some properties seem to update immediately (e.g. OrthoWidth on a CameraComponent). Also noticed when changing the relative location that I do get a “reset to default” prompt in the blueprint editor.

1 Like