SpawnActor not working with collision

Just messing around with some things in unreal since I’m new to it but I have some very simple code that spawns a static mesh actor into the world when the user presses a button. That spawned actor does not seem to have any collision even though it should and I can’t figure out what I’m missing.

Specific code is in OnSecondaryAction

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.

#include "Oxidation.h"
#include "OxidationCharacter.h"
#include "OxidationProjectile.h"
#include "Animation/AnimInstance.h"
#include "GameFramework/InputSettings.h"
#include "Runtime/Engine/Classes/Engine/StaticMeshActor.h"

DEFINE_LOG_CATEGORY_STATIC(LogFPChar, Warning, All);

//////////////////////////////////////////////////////////////////////////
// AOxidationCharacter

AOxidationCharacter::AOxidationCharacter()
{
	// Set size for collision capsule
	GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);

	// set our turn rates for input
	BaseTurnRate = 45.f;
	BaseLookUpRate = 45.f;

	// Create a CameraComponent	
	FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
	FirstPersonCameraComponent->AttachParent = GetCapsuleComponent();
	FirstPersonCameraComponent->RelativeLocation = FVector(0, 0, 64.f); // Position the camera
	FirstPersonCameraComponent->bUsePawnControlRotation = true;

	// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
	Mesh1P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh1P"));
	Mesh1P->SetOnlyOwnerSee(true);
	Mesh1P->AttachParent = FirstPersonCameraComponent;
	Mesh1P->bCastDynamicShadow = false;
	Mesh1P->CastShadow = false;

	// Create a gun mesh component
	FP_Gun = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FP_Gun"));
	FP_Gun->SetOnlyOwnerSee(true);			// only the owning player will see this mesh
	FP_Gun->bCastDynamicShadow = false;
	FP_Gun->CastShadow = false;
	FP_Gun->AttachTo(Mesh1P, TEXT("GripPoint"), EAttachLocation::SnapToTargetIncludingScale, true);

	// Default offset from the character location for projectiles to spawn
	GunOffset = FVector(100.0f, 30.0f, 10.0f);

	// Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P are set in the
	// derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}

//////////////////////////////////////////////////////////////////////////
// Input

void AOxidationCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	// set up gameplay key bindings
	check(InputComponent);

	InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
	InputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);

	InputComponent->BindAction("PrimaryAction", IE_Pressed, this, &AOxidationCharacter::OnPrimaryAction);

	InputComponent->BindAction("SecondaryAction", IE_Pressed, this, &AOxidationCharacter::OnSecondaryAction);

	InputComponent->BindAxis("MoveForward", this, &AOxidationCharacter::MoveForward);
	InputComponent->BindAxis("MoveRight", this, &AOxidationCharacter::MoveRight);

	// We have 2 versions of the rotation bindings to handle different kinds of devices differently
	// "turn" handles devices that provide an absolute delta, such as a mouse.
	// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
	InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
	InputComponent->BindAxis("TurnRate", this, &AOxidationCharacter::TurnAtRate);
	InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
	InputComponent->BindAxis("LookUpRate", this, &AOxidationCharacter::LookUpAtRate);
}

void AOxidationCharacter::OnPrimaryAction()
{
	// try and fire a projectile
	if (ProjectileClass != NULL)
	{
		const FRotator SpawnRotation = GetControlRotation();
		// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
		const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

		UWorld* const World = GetWorld();
		if (World != NULL)
		{
			// spawn the projectile at the muzzle
			World->SpawnActor<AOxidationProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
		}
	}

	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if (FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if (AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}
}

void AOxidationCharacter::OnSecondaryAction()
{
	UE_LOG(LogTemp, Log, TEXT("-Spawning AStaticMeshActor Foundation-"));

	const FRotator SpawnRotation = GetControlRotation();
	const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

	AStaticMeshActor* foundation = GetWorld()->SpawnActor<AStaticMeshActor>(SpawnLocation, FRotator::ZeroRotator);
	foundation->GetStaticMeshComponent()->StaticMesh = BuildingFoundation;
	foundation->GetStaticMeshComponent()->SetEnableGravity(false);
}

void AOxidationCharacter::MoveForward(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorForwardVector(), Value);
	}
}

void AOxidationCharacter::MoveRight(float Value)
{
	if (Value != 0.0f)
	{
		// add movement in that direction
		AddMovementInput(GetActorRightVector(), Value);
	}
}

void AOxidationCharacter::TurnAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}

void AOxidationCharacter::LookUpAtRate(float Rate)
{
	// calculate delta for this frame from the rate information
	AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}

Where “BuildingFoundation”:

    	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
    	class UStaticMesh* BuildingFoundation;

Which is just the “Floor_400x400” Static Mesh from the Starter Content.

If I place the “Floor_400x400” into the editor before run time, the collision seems to work fine on that actor but after spawning it into the world at run time and there is no collision on it. If I toggle a random physics/collision property on the spawned actor during run time in the editor, only then does collision seem to start working. Not sure if this is a bug or if I’m just missing some kind of “enable collision right away” method or property on the static mesh actor but any help would be appreciated.

Hello ,

Could you post the rest of the code for the class that this SpawnActor is being called in? I tried reproducing the same issue but my spawned AStaticMeshActor had collision. The issue could be elsewhere.

Hey ,

I just edited my post to contain the full code from the respective class. Its just a stripped down version of the OxidationCharacter.cpp code from the first person template when making a new project. Have not added anything new to the code that you get from it other than this.

Do you change any settings elsewhere for this? I’m assuming BuildingFoundation is a UStaticMesh pointer. When I go to run the exact code you listed, the StaticMeshActors will spawn but remain invisible due to being set to Static by default. I added the following line to make them appear after spawning. Do you see this same behavior?

foundation->GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);

I don’t believe I have changed any other settings. Yes, BuildingFoundation is defined as:
class UMaterial* BuildingFoundationMaterial;

I had saw the invisible StaticMeshActor, but I just set it to a material as follows:
foundation->GetStaticMeshComponent()->SetMaterial(0, BuildingFoundationMaterial);

Where BuildingFoundationMaterial is just:
class UMaterial* BuildingFoundationMaterial;

When I do this, I saw the StaticMeshActor but it did not have collision. However, your line from above of making the actor movable allows collision to work right away. Is that something specific with StaticMeshActors being spawned from code? The StaticMeshActors I have defined in the editor from dragging and dropping the StaticMesh asset to the game are all defaulted to Static yet collision works on them. I’m curious as to why there is such a difference and if there is something I’m just missing.

Thank you for working with me on this . I’ve placed a bug into our system for both issues, the fact that the StaticMeshActor needs to be edited before it’ll visibly appear and that, when set to static, it has no collision. For your reference, the bug number is UE-24754. I’ll be sure to let you know when any updates are made to the report. In the meantime I’d suggest setting the StaticMeshActor to moveable to avoid the issue.

Have a nice day!

Much appreciated. Thanks for stepping through it with me. Happy that I at least have a work around for now.

Hi,

I’ve taken a look at the project and the stripped-down example that put together for this to be looked at (thanks!).

The issue can be addressed by doing the following:

  • Call SetStaticMesh() instead of setting the StaticMesh property directly.
  • Make sure that the static mesh component is set to Moveable if the mesh property needs to be changed at runtime. Meshes with static mobility cannot be changed after component registration. Alternatively you could unregister/reregister the component, but that would be less efficient.

We are looking to deprecate the public access of this variable soon!

Hey thanks for the feedback. Works like a charm and makes sense. I’m going to this as the correct answer despite 's immense help as its the technically correct solution.