x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Spawning Actor with child Actor when dragged into scene

I want to Spawn an Actor with a child Actor when dragging the parent Actor into the scene. It is working but another child actor is spawned without being attached to the parent actor. Here my approach.

 ASpawningActor::ASpawningActor()
 {
      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it. 
     
     PrimaryActorTick.bCanEverTick = false;
     bReplicates = true;
 
     UStaticMesh* Mesh = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, TEXT("StaticMesh'/Game/Geometry/Meshes/1M_Cube.1M_Cube'")));
     UMaterial* Material = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("Material'/Game/Geometry/Meshes/CubeMaterial.CubeMaterial'")));
     
     
     UStaticMeshComponent* MeshComponent = NewObject<UStaticMeshComponent>(this, UStaticMeshComponent::StaticClass(), TEXT("StaticMesh"));
 
     if (!ensure(Mesh) || !ensure(Material) || !ensure(MeshComponent)) { return; }
     MeshComponent->SetStaticMesh(Mesh);
     MeshComponent->SetMaterial(0, Material);
     MeshComponent->SetWorldLocation(FVector(0.0f, 0.0f, 0.0f));
     MeshComponent->RegisterComponent();
     this->AddOwnedComponent(MeshComponent);
     this->SetRootComponent(MeshComponent); 
 }
 
 // Called when the game starts or when spawned
 void ASpawningActor::BeginPlay()
 {
     Super::BeginPlay();
 }
 
 // Called every frame
 void ASpawningActor::Tick(float DeltaTime)
 {
     Super::Tick(DeltaTime);
 }
 
 void ASpawningActor::PostActorCreated()
 {
     FActorSpawnParameters SpawnInfo;
     Actor = GetWorld()->SpawnActor<AStreetActor1>(FVector(0.0f, 0.0f, 0.0f), FRotator(0.0f, 0.0f, 0.0f), SpawnInfo);
     Actor->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
 }

I don't use OnConstruction because child actors getting spawned all the time when moving the parent actor around. The old one won't get destroyed.

alt text

Product Version: UE 4.19
Tags:
clipboard01.jpg (6.7 kB)
more ▼

asked Sep 02 '18 at 08:27 PM in C++ Programming

avatar image

Merkaber
1 1 3

avatar image dZh0 Sep 03 '18 at 01:10 PM

... but another child actor is spawned without being attached ...

Do you mean:

  1. that the spawned actor is not attached?

  2. that the spawned actor is attached but second one is created (and not attached)?

It's ok that you don't use OnConstruction() although you can check IsValid(Actor) before spawning, which will prevent it from creating multiple copies.

Anyways I would imagine that PostActorCreated() is better.

avatar image Merkaber Sep 03 '18 at 01:42 PM

There is one Actor which I drag into the scene (SpawnedActor) and one who gets created when doing so (StreetActor). I need to have this hierarchy in order to move the parent actor and everything gets moved around with it together. When pressing the mouse and draggin into the scene one parent actor and its child gets created. That is fine. However, when I then release the mouse button another StreetActor is getting spawned, not being attached (as shown in the picture). I tried IsValid, but it doesn't seems to work.

 FActorSpawnParameters SpawnInfo1;
 AStreetActor1* Actor1 = GetWorld()->SpawnActor<AStreetActor1>(FVector(4025.339103f, 4016.818612f, -8459.981933f), FRotator(0.0f, 0.0f, 0.0f), SpawnInfo1);
 if (IsValid(Actor1))
     {
         Actor1->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
     }
avatar image dZh0 Sep 03 '18 at 02:01 PM

Can you add a trace and try to encapsulate the spawner in the validation check like this:

 //other code...
 void ASpawningActor::PostActorCreated()
 {
     UE_LOG(LogTemp, Warning, TEXT("Post Create Call by: %s"), this->GetName().ToString());
     if (!IsValid(Actor))
     {
         FActorSpawnParameters SpawnInfo;
         Actor = GetWorld()->SpawnActor<AStreetActor1>(FVector(0.0f, 0.0f, 0.0f), FRotator(0.0f, 0.0f, 0.0f), SpawnInfo);
         Actor->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
     }
 }

Note that there might be some errors as I got no compiler on the phone ;)

Please show the log with "Post Create Call by: X" to see if there are multiple objects that call it or just one.

avatar image Merkaber Sep 03 '18 at 03:17 PM

Thats the result of the trace:

alt text

but...:

alt text

this happens. I just want to spawn it once :( So PostActorCreated gets called twice. First: When dragging into scene, Second: When releasing the mouse button.

clipboard01.jpg (16.2 kB)
clipboard02.jpg (7.5 kB)
avatar image dZh0 Sep 03 '18 at 07:06 PM

It is called by 2 different actors - SpawningActor_0 and SpawningActor_1... Are you sure you don't have 2 of those on the scene?

avatar image Merkaber Sep 04 '18 at 12:56 PM

So it looks like that: When I drag the parent actor into the scene he gets created and PostActorCreate gets called. When releasing the mouse button the parent actor gets destroyed and another one gets created and PostActorCreated gets called again. Thats why I have 2 child actors but only 1 parent actor. I came to this idea because the number of the parent actor changes after releasing the mouse button.

avatar image dZh0 Sep 04 '18 at 01:52 PM

Ahh! Those post- methods are all so badly documented :(

You said you don't use OnConstruction() but have you tried it with bRunConstructionScriptOnDrag = false? Alternately you can try AActor::PostActorConstruction().

There are a bunch more and I doubt anyone knows why there are 10+ post- and on- construction methods: AActor::PostSpawnInitialize(), AActor::PostInitializeComponents(), AActor::PostRegisterAllComponents(), ...

avatar image Merkaber Sep 04 '18 at 03:16 PM

So I tried bRunConstructionScriptOnDrag = false and it ends up with the same result as shown in the picture. I really would like to try AActor::PostActorConstruction() but it's not a virtual method. Is there a way to access those methods in any way eventhough they are not virtual? Or is there a way to do something after they get called? I am not that deep into c++ yet. Thank you for your effort!

(comments are locked)
10|2000 characters needed characters left

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question