4

I'm making a laser tag game in UE4 and I'm having a ton of difficulty using TSubclassOf<>.

First, I'm declaring LaserClass in my LaserTagCharacter.h file like this. I'm also creating a function called OnFire() that's called when the player uses the "Fire" action binding.

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "LaserTagCharacter.generated.h"

UCLASS()
class LASERTAG_API ALaserTagCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // Sets default values
    ALaserTagCharacter();

    UPROPERTY(VisibleAnywhere, Category = "Laser")
    TSubclassOf<class ALaserTagLaser> LaserClass;

protected:
    // Called when player fires a laser beam
    void OnFire();
};

Now I want to implement my OnFire() function to create a laser from my ALaserTagLaser class using a SpawnActor<> function. I'm doing that like this.

#include "LaserTagCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "LaserTagLaser.h"
#include "Engine/World.h"

// Sets default values
ALaserTagCharacter::ALaserTagCharacter()
{

}

// Called when player uses fire action binding
void ALaserTagCharacter::OnFire()
{
    UWorld* World = GetWorld();
    FVector SpawnLocation = GetActorLocation();
    FRotator SpawnRotation = GetControlRotation();
    FActorSpawnParameters SpawnParameters;
    SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

    World->SpawnActor<ALaserTagLaser>(LaserClass, GetActorLocation(), GetActorRotation(), SpawnParameters);
}

All of this code compiles, but when I click play, open the output log, and use my "Fire" action binding I get this error.

LogSpawn: Warning: SpawnActor failed because no class was specified

I'm confused because I clearly specified what class I wanted to be spawn. If anyone can offer some insight that would be awesome.

pat-lawre
  • 97
  • 2
  • 14

2 Answers2

1

TSubclassOf is just a UClass*. In your code, you never assign it. So it's always LaserClass == nullptr.

For the actor to spawn correctly, you need to assign the LaserClass variable to the class you intend to use. For example, if you want to spawn a ALaserTagLaser call LaserClass = ALaserTagLaser::Static_Class() before your SpawnActor.

If you want to assign a BP class to LaserClass, then set it in the Unreal editor. For this, you need to either set it with a set LaserClass node in the Blueprint graph, with the target being an instance of ALaserTagCharacter, or by selecting a default value in a child class of ALaserTagCharacter in details panel in the dropdown.

goose_lake
  • 847
  • 2
  • 15
0

You need to assign LaserClass a valid class or subclass. In your BP, you can set it in the details panel. If you don't want to use it like that in a BP and always want to spawn a ALaserTagLaser, you can just give SpawnActor a class reference instead.

World->SpawnActor<ALaserTagLaser>(ALaserTagLaser::StaticClass(), GetActorLocation(), GetActorRotation(), SpawnParameters);
nikals
  • 136
  • 1
  • 4