Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIXME: AActorSingleton::TryBecomeNewInstanceOrSelfDestroy WITH_EDITOR behavior #2

Open
sleeptightAnsiC opened this issue Jul 15, 2024 · 0 comments

Comments

@sleeptightAnsiC
Copy link
Owner

sleeptightAnsiC commented Jul 15, 2024

I shall at least try to refactor this someday:

#if WITH_EDITOR
/* In case of placing an Actor in the Level Viewport, we canNOT simply Destroy it.
* Instead, we must "tell" the Editor to delete it, which will fire some additional clean up logic.
* Also we're showing a message to the Editor user telling what is happening, so we can avoid confusion.
*
* FIXME: Current implementation is fine but has few caveats:
* 1. it "touches" the Level despite that no actual changes have been done
* 2. if user uses 'undo' after deletion, the duplicate object will be restored
* 3. if user's Actor does something after being placed, we won't be able to revert it
* These are pretty bad... I should probably find another way to achieve the same goal.
*
* TODO: Possible solutions for the issues listed above:
* 1. Prevent Actor from being placed into the Level in the first place
* I have no idea if this can be achieved with Unreal Engine...
* If that's possible, then there is probably some kind of Interface in AActor that allows it
* but otherwise I have no clue where to look for solution
* 2. Instead of deletion, we can simply use Editor's 'undo' feature
* The problem with this one is that we would never know for sure how many times call the 'undo'
* because Actor, when placed, can do some other stuff around which adds up to the undo/redo buffer.
* We would need to find out how many times we need to call the 'undo'
* However, this option seems the most promising and possible to implement :)
*/
if (ThisWorld->IsEditorWorld() && !ThisWorld->IsPlayInEditor())
{
/* Show Dialogue Message */
const FText MessageTitle = this->GetMessageTitle();
const FText MessageBody = this->GetMessageBody();
FMessageDialog::Debugf(MessageBody, MessageTitle);
/* Delete 'this' via UEditorActorSubsystem */
auto* EditorActorSubsystem = GEditor->GetEditorSubsystem<UEditorActorSubsystem>();
check(EditorActorSubsystem)
EditorActorSubsystem->ClearActorSelectionSet();
EditorActorSubsystem->SetActorSelectionState(this, true);
EditorActorSubsystem->DeleteSelectedActors(ThisWorld);
GEngine->ForceGarbageCollection(true);
/* Garbage Actor still seems to be selected in the Details Panel despite already being destroyed.
* 'UEditorActorSubsystem::DeleteSelectedActors' doesn't handle this by itself,
* so we are clearing the Actor selection on the very next tick which fixes this issue. */
ThisWorld->GetTimerManager().SetTimerForNextTick(
[&]()->void
{
EditorActorSubsystem->SelectNothing();
}
);
return;
}
#endif //WITH_EDITOR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant