Hi,
I could create static meshes, materials and lights, yet, I just cannot add a ChildActor component in an Actor scenegraph
UChildActorComponent* UMyFunctionLibrary::AddChildActorComponent(FString name, AActor* OwningActor, TSubclassOf<AActor> InClass)
{
UChildActorComponent* ChildActorComponent = NewObject<UChildActorComponent>(OwningActor, UChildActorComponent::StaticClass(), FName(name + "ChildActor"));
ChildActorComponent->AttachToComponent(OwningActor->GetRootComponent(), FAttachmentTransformRules::SnapToTargetNotIncludingScale);
ChildActorComponent->RegisterComponent();
ChildActorComponent->SetChildActorClass(InClass);
ChildActorComponent->CreationMethod = EComponentCreationMethod::UserConstructionScript;
return ChildActorComponent;
}
thanks for your help
anyone ? I am really stuck on this
3dRaven
(3dRaven)
May 2, 2023, 4:13pm
3
Your code works. Just make sure owning actor is at least hooked up to the parent class that is spawning it, otherwise the engine spews out errors and crashes.
Perhaps a nullptr check before going through with the function would help?
UChildActorComponent* UMyFunctionLibrary::AddChildActorComponent(FString name, AActor* OwningActor, TSubclassOf<AActor> InClass)
{
if (OwningActor!=nullptr) {
UChildActorComponent* ChildActorComponent = NewObject<UChildActorComponent>(OwningActor, UChildActorComponent::StaticClass(), FName(name + "ChildActor"));
ChildActorComponent->AttachToComponent(OwningActor->GetRootComponent(), FAttachmentTransformRules::SnapToTargetNotIncludingScale);
ChildActorComponent->RegisterComponent();
ChildActorComponent->SetChildActorClass(InClass);
ChildActorComponent->CreationMethod = EComponentCreationMethod::UserConstructionScript;
return ChildActorComponent;
}
else return nullptr;
}
1 Like
I still have the same issue, if ran from the constructor, it works
if I run it from a button, from the actor instance in the editor, it does not
I need to run it outside of the constructor to pass data that are set in the editor and not there when constructor runs
[edit/ it works but the added component dont show in actor’s scenegraph]
3dRaven
(3dRaven)
May 2, 2023, 6:57pm
5
I ran it on begin play no problems. Running from the constructor is not even a good idea because you are using newObject that lies outside of the scope of the cdo.
I adapt based on a buildfromconstructor boolean
yet why is the added childactor not displaying in the scenegraph ?
3dRaven
(3dRaven)
May 2, 2023, 7:01pm
7
Are you referring to the outliner? If so then it does appear as a new actor below the parent actor (you have to expand the arrow next to it)
Objects created with newObject will not show up in the blueprint editor in the component tab if that is what you mean. It’s a creation at runtime so it’s only visible in the editor and outliner.
oh, I did not know
I want to click on a button and the scenegraph in the actor’s scenegraph to be updated
cos otherwise saving the actor wont save the modifications
3dRaven
(3dRaven)
May 2, 2023, 7:12pm
9
You can’t save modifications done at runtime to actor by default. You have to program a save / load mechanism
You could make a blueprint based on savegame and save out the actors modifications and then load them on begin play.
If you only want to change an object that is placed on the scene then an editor utility widget could also call the blueprint function on the selected object. But this would only work in the editor and not in a published game.
I try to create an import system
importing in the scene is ok but indeed importing in the actors themselves seems to be an issue
also that childactor is not getting parented to the actor at runtime, it is linked to it but does not appear under the actor in the outliner
3dRaven
(3dRaven)
May 2, 2023, 7:18pm
11
This is what it looks like during runtime when I add the child actor on key press.
Key press event
Truck being the main actor
created in the constructor
and replaced as I click the button at runtime
called from constructor or button
void UMyFunctionLibrary::BuildActorStructure(AActor* OwningActor, FString BlenderCsvToImportPath, TArray<USceneComponent*>& EditableSceneComponents, TArray<UStaticMesh*> Meshes,bool importFromConstructor, TMap<FString, UPlaceHolderDataAsset*> PlaceHolderDataAssets)
{
USphereComponent* RootSphereComponent;
if (importFromConstructor)
{
RootSphereComponent = OwningActor->CreateDefaultSubobject<USphereComponent>(FName("SphereComponent"));
}
else
{
RootSphereComponent = NewObject<USphereComponent>(OwningActor, USphereComponent::StaticClass(), FName("SphereComponent"));
}
RootSphereComponent->SetWorldScale3D(FVector(1, 1, 1));
if (OwningActor->GetRootComponent())
{
TArray<USceneComponent*> _Children;
OwningActor->GetRootComponent()->GetChildrenComponents(false, _Children);
for (auto child : _Children)
{
child->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
}
RootSphereComponent->AttachToComponent(OwningActor->GetRootComponent(), FAttachmentTransformRules::SnapToTargetNotIncludingScale);
RootSphereComponent->RegisterComponent();
}
else
{
OwningActor->SetRootComponent(RootSphereComponent);
}
RootSphereComponent->SetVisibleFlag(false);
UChildActorComponent* ChildActorComponent = AddChildActorComponent(test, OwningActor, AMyCppPlaceHolder::StaticClass(), importFromConstructor);
EditableSceneComponents.Add(ChildActorComponent);
}
3dRaven
(3dRaven)
May 2, 2023, 7:42pm
13
UChildActorComponent* UMyFunctionLibrary::AddChildActorComponent(FString name, AActor* OwningActor, TSubclassOf<AActor> InClass, bool importFromContructor)
{
UChildActorComponent* ChildActorComponent = nullptr;
if (OwningActor != nullptr) {
if (importFromContructor) {
ChildActorComponent = OwningActor->CreateDefaultSubobject<UChildActorComponent>(FName(name + "ChildActor"));
ChildActorComponent->SetupAttachment(OwningActor->GetRootComponent());
}
else {
ChildActorComponent = NewObject<UChildActorComponent>(OwningActor, UChildActorComponent::StaticClass(), FName(name + "ChildActor"));
ChildActorComponent->AttachToComponent(OwningActor->GetRootComponent(), FAttachmentTransformRules::SnapToTargetNotIncludingScale);
ChildActorComponent->RegisterComponent();
}
ChildActorComponent->SetChildActorClass(InClass);
ChildActorComponent->CreationMethod = EComponentCreationMethod::UserConstructionScript;
return ChildActorComponent;
}
else return nullptr;
}
You can only register components with newObject.
in the case of a constructor you attach with setupAttachment
ok
I tried calling all this from an override of begin play, nothing gets created as I run the game,
is there no updated documentation about this ? the only doc I found uses CreateSubObject which is deprecated
yeah but is not c++
also setupAttachment needs a socket name, I dont use sockets
3dRaven
(3dRaven)
May 3, 2023, 3:06pm
17
setupAttachment socket name is optional.
All code so far has been in c++. The only blueprint is the input that triggers the static code.
I just cannot make this work, constructor, button, or in game
nothing works
I’ll try with blueprints