I updated transform of actor via Actor Utility Blueprint (Scripted Action) and found that viewport’s transform gizmo kept staying at the location it was originally.
I found this work around: you can reselect modified actor with the Set Selected Level Actors node. The reselection will update gizmo position.
I know this is an older thread, but I’m working on a similar problem.
I’d like to add a C+±based solution to the answer. I’m not sure it’s helpful for the original poster, but it might be useful for anyone else looking at this thread.
I created a method in C++ called “InvalidateViewport” which takes the actor I’m moving as an argument.
The method is called in blueprints after moving the actor. It takes finds the difference between the location of the actor that was just moved and the location of the transform widget. It then applies that difference to the transform widget.
I determined this method mostly by hunting around in the engine source. I’m not sure it’s a “good” way to do it, but it seems to work. I believe it will only work in “Editor-only” code.
Here’s the method:
void WidgetBase::InvalidateViewport(AActor * modifiedActor)
{
// determine the current location of the transform widget
FEditorViewportClient* client = (FEditorViewportClient*)GEditor->GetActiveViewport()->GetClient();
auto widgetLocation = client->GetWidgetLocation();
// find the difference between the transform widget and the actor that was just
// moved (in the blueprint that is calling this method).
auto actorLocation = modifiedActor->GetActorLocation();
auto delta = actorLocation - widgetLocation;
// we don't need to apply rotation or scale to the transform widget.
auto rotation = FRotator(0, 0, 0);
auto scale = FVector(0, 0, 0);
// apply the difference in location to the transform widget.
client->InputWidgetDelta(
client->Viewport, EAxisList::All, delta, rotation, scale);
// invalidate the viewport to redraw.
client->Viewport->Invalidate();
// not sure if this is a better call to make
// client->Invalidate(true, true);
}
And here’s an image of it being called in Blueprints as part of an Undo Transaction:
Cpp code works well !
You have to keep in mind to use InputWidgetDelta insteaf of set the actor location.
If you look at the source code of the FEditorViewportClient::InputWidgetDelta() method, you will see how you can specify the location and rotation of the editor viewport gizmo:
#include "EditorViewportClient.h"
#include "EditorModeManager.h"
void SetEditorGizmoTransform(const FTransform NewTransform){
FEditorViewportClient* EditorViewportClient = (FEditorViewportClient*)GEditor->GetActiveViewport()->GetClient();
FEditorModeTools* ModeTools = EditorViewportClient->GetModeTools();
if (ModeTools->AllowWidgetMove()) {
ModeTools->PivotLocation = NewTransform.GetLocation();
ModeTools->SnappedLocation = NewTransform.GetLocation();
}
ModeTools->TranslateRotateXAxisAngle = NewTransform.Rotator().Yaw;
ModeTools->TranslateRotate2DAngle = NewTransform.Rotator().Pitch;
}