SpawnActor not to set location

As the title suggests, when I cut the tree instead of spawning the trunk and tree top to make the tree fall at the original tree location, instead it spawns at 0,0,0.

Even though the FTransform is correctly logged.

Here is the code:

void UTreeTrace::CutTreeInReach()
{
	FHitResult HitResult;
	bool HasHit = GetTreeInReach(HitResult);

	if(HasHit && Cast<ACuttableTree>(HitResult.GetActor()))
	{
		Tree = Cast<ACuttableTree>(HitResult.GetActor());
		FTransform TrunkSpawnTransform = Tree->GetActorTransform();
		FVector TrunkSpawnLocation = Tree->GetActorLocation();
		FRotator TrunkSpawnRotation = Tree->GetActorRotation();

		UE_LOG(LogTemp, Warning, TEXT("TrunkSpawnTransform : %s "), *TrunkSpawnTransform.ToString());
		auto TrunkUClass = Cast<UClass>(Tree->Trunk);
		auto TreeTopUClass = Cast<UClass>(Tree->TreeTop);
		FActorSpawnParameters Params;
		// GetWorld()->SpawnActor(TrunkUClass, &TrunkSpawnTransform);
		// GetWorld()->SpawnActor(TreeTopUClass, &TrunkSpawnTransform);
		GetWorld()->SpawnActor(TrunkUClass, &TrunkSpawnLocation, &TrunkSpawnRotation, Params);
		GetWorld()->SpawnActor(TreeTopUClass, &TrunkSpawnLocation, &TrunkSpawnRotation, Params);
		Tree->Destroy();

		
	}

	
}

Why are you using & before location and rotation? My code doesn’t even compile if I do that. Try removing these signs and see what happens.

I get an error saying that it’s not a viable function if I remove the &.

I think he’s calling this overload of SpawnActor:

AActor* UWorld::SpawnActor( UClass* Class, FVector const* Location, FRotator const* Rotation, const FActorSpawnParameters& SpawnParameters )
{
	FTransform Transform;
	if (Location)
	{
		Transform.SetLocation(*Location);
	}
	if (Rotation)
	{
		Transform.SetRotation(FQuat(*Rotation));
	}

	return SpawnActor(Class, &Transform, SpawnParameters);
}

I don’t understand why it uses pointers and not references (maybe historical reasons?)

Oh wait, maybe it’s so that they can default the parameters:

AActor* SpawnActor( UClass* InClass, FVector const* Location=NULL, FRotator const* Rotation=NULL, const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters() );`

I think I would have created separate overloads for the different arities rather than doing this, but whatever.

That’s odd.
Maybe it’s because of getting classes this way. I generally declare TSubclassOf<> and set the class reference manually because I create blueprints based on c++ classes for customization purposes. And since here the newly created UClass is probably a pointer, it calls the overloaded function with pointers.

What instead of casting to UClass you just get Tree->Trunc::StaticClass() ?

  • What is the actor classes ESpawnActorCollisionHandlingMethod ? The default behaviour of SpawnActor is to use the actors setting.

  • I would debug this by setting a breakpoint and then stepping in following the value of transform until the actor spawns and its root component transform is set. It’s not far I don’t think.

Ok, I set the `ESpawnActorCollisionHandlingMethod::AlwaysSpawn to ignore collision thinking that this would help but it did not. I watched the transform on spawn in debug and even though it is passed correctly from the FTransform variable it continues to spawn at 0,0,0.

Also tried AdjustIfPossibleButDontSpawnIfColliding and it still spawns at 0,0,0, so it’s not a collision problem in my undestanding.

Strange.

I did pass only the tree->trunk afterward of posting this question once I changed the original class from static mesh to TSubclassOf as you mentioned.

It’s spawning the parts I need normally therefore, thanks!

1 Like

Sorry, I don’t understand. Are you saying the bug is fixed now? Or is it still not working?

@zos Still not working. I don’t know why instead of setting the location to the referenced one it sets it to the default 0,0,0 . Still trying different possible solutions in order to figure out why this is happening.

I’d keep trying with the debugger. Follow the transform value until it gets set on the root component. At some point it has to change from your setting to zero. It does show zero vector when you play-in-editor and look at the actor in the outliner right?

Oh, I skipped a very important part of your reply. The root component. The root component does take the correct transform but the static mesh does not.

Sooooo, I figured it out. I did an oopsie.

So I created the ATreePart [Static Mesh Actor] class that was either the trunk or the TreeTop parts of the tree. Mistakenly I created a Default subobject inside the ATreePart and assigned there my static mesh [in the constructor, of course, attached to the root component].

The problem that arises was that because it is a StaticMeshActor the engine didn’t track secondary static meshes or some sort of that, and it did not assign the aforementioned transform to the created static mesh as a subobject but only applied the transform to its original static mesh.

Now that I removed the secondary static mesh from ATreePart, upon cutting the tree, the two parts, trunk and tree top, spawn at the passed transform.

Thank you all for the help and guidance to the solution, as well as for your time spent with my issue.

Cheers.

1 Like

No problem. Glad you got it fixed.