Creating a custom Scene Component

Scene Components are a subclass of Actor Components that have a transform, that is, a relative location, rotation, and scale. Just like Actor Components, Scene Components aren't rendered themselves, but can use their transform for various things, such as spawning other objects at a fixed offset from an Actor.

How to do it...

  1. Create a custom SceneComponent called ActorSpawnerComponent. Make the following changes to the header:
    UFUNCTION()
    void Spawn();
    UPROPERTY()
    TSubclassOf<AActor> ActorToSpawn;
  2. Add the following function implementation to the cpp file:
    void UActorSpawnerComponent::Spawn()
    {
      UWorld* TheWorld = GetWorld();
      if (TheWorld != nullptr)
      {
        FTransform ComponentTransform(this->GetComponentTransform());
        TheWorld->SpawnActor(ActorToSpawn,&ComponentTransform);
      }
    }
  3. Verify your code against this snippet:
    ActorSpawnerComponent.h
    #pragma once
    
    #include "Components/SceneComponent.h"
    #include "ActorSpawnerComponent.generated.h"
    
    UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
    class UE4COOKBOOK_API UActorSpawnerComponent : public USceneComponent
    {
      GENERATED_BODY()
    
      public:
      UActorSpawnerComponent();
    
      virtual void BeginPlay() override;
    
      virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
    
      UFUNCTION(BlueprintCallable, Category=Cookbook)
      void Spawn();
    
      UPROPERTY(EditAnywhere)
      TSubclassOf<AActor> ActorToSpawn;
    
    };
    ActorSpawnerComponent.cpp
    #include "UE4Cookbook.h"
    #include "ActorSpawnerComponent.h"
    
    UActorSpawnerComponent::UActorSpawnerComponent()
    {
      bWantsBeginPlay = true;
      PrimaryComponentTick.bCanEverTick = true;
    }
    
    void UActorSpawnerComponent::BeginPlay()
    {
      Super::BeginPlay();
    }
    
    void UActorSpawnerComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
    {
      Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
    }
    
    void UActorSpawnerComponent::Spawn()
    {
      UWorld* TheWorld = GetWorld();
      if (TheWorld != nullptr)
      {
        FTransform ComponentTransform(this->GetComponentTransform());
        TheWorld->SpawnActor(ActorToSpawn,&ComponentTransform);
      }
    }
  4. Compile and open your project. Drag an empty Actor into the scene and add your ActorSpawnerComponent to it. Select your new Component in the Details panel, and assign a value to ActorToSpawn. Now whenever Spawn() is called on an instance of your component, it will instantiate a copy of the Actor class specified in ActorToSpawn.

How it works...

  1. We create the Spawn UFUNCTION and a variable called ActorToSpawn. The ActorToSpawn UPROPERTY is of type TSubclassOf< >, a template type that allows us to restrict a pointer to either a base class or subclasses thereof. This also means that within the editor, we will get a pre-filtered list of classes to pick from, preventing us from accidentally assigning an invalid value.
    How it works...
  2. Inside the Spawn function's implementation, we get access to our world, and check it for validity.
  3. SpawnActor wants an FTransform* to specify the location to spawn the new actor, so we create a new stack variable to contain a copy of the current component's transform.
  4. If TheWorld is valid, we request it to spawn an instance of the ActorToSpawn-specified subclass, passing in the address of the FTransform we just created, and which now contains the desired location for the new actor.

See also

  • Chapter 8, Integrating C++ and the Unreal Editor, contains a much more detailed investigation into how you can make things Blueprint-accessible.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.104.149