Unreal Engine, from C++ add an ActorComponent to an Actor, very small example

From Andreida

Needed Code

I am using "Unreal Engine, from C++ spawn Blueprint inherited from C++ class, very small example" as a base for this example. Consider to do that first if you are unsure.

Create ActorComponent class

  • Tools / New C++ Class
    • Parent Class: ActorComponent
    • Name: AcRandomScaleChange
    • Create Class

Header File: AcRandomScaleChange.h

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AcRandomScaleChange.generated.h"

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class SHOWACTOR_API UAcRandomScaleChange : public UActorComponent
{
  GENERATED_BODY()

public:	
  UAcRandomScaleChange();

protected:
  virtual void BeginPlay() override;
  virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

  UPROPERTY()
  float m_fSecondsSinceUpdate;

  UPROPERTY()
  float m_fSecondsBetweenUpdates;

  UPROPERTY()
  float m_fScaleChange;
};

Source File: AcRandomScaleChange.cpp

#include "AcRandomScaleChange.h"

UAcRandomScaleChange::UAcRandomScaleChange()
  : m_fSecondsSinceUpdate(0)
  , m_fSecondsBetweenUpdates(0.4)
  , m_fScaleChange(0.1)
{
  PrimaryComponentTick.bCanEverTick = true;
}

void UAcRandomScaleChange::BeginPlay()
{
  Super::BeginPlay();
}

void UAcRandomScaleChange::TickComponent(float fDeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
  Super::TickComponent(fDeltaTime, TickType, ThisTickFunction);

  m_fSecondsSinceUpdate += fDeltaTime;
  if (m_fSecondsSinceUpdate < m_fSecondsBetweenUpdates)
    return;

  AActor* pParent = GetOwner();
  if (pParent)
  {
    FVector vScale(pParent->GetActorRelativeScale3D());
    vScale.X += FMath::FRandRange(-1.0, 1) * m_fScaleChange * m_fSecondsSinceUpdate;
    vScale.Y += FMath::FRandRange(-1.0, 1) * m_fScaleChange * m_fSecondsSinceUpdate;
    vScale.Z += FMath::FRandRange(-1.0, 1) * m_fScaleChange * m_fSecondsSinceUpdate;
    pParent->SetActorRelativeScale3D(vScale);
  }

  m_fSecondsSinceUpdate = 0.0;
}

Use Actor Component in Actor class

changes to Header File: MiniActor.h

add the following

#include "AcRandomScaleChange.h"
UPROPERTY()
UAcRandomScaleChange* m_pAcRandomScaleChange;

changes to Source File: MiniActor.cpp

add the following in AMiniActor::AMiniActor()

/// Why do I not have to give "this" as parent somehow?
m_pAcRandomScaleChange = CreateDefaultSubobject<UAcRandomScaleChange>("RandomScaleChange");

Now build in your Visual Studio and "play" in the editor.

Info

I am not sure about this example. Yes, it works. But perhaps it shouldn't exist? If only I knew if the following quote is true:

So basically ActorComponents are for the most basic of functionality
which doesnt require access to a transform (location, rotation, scale) and
SceneComponents allow things like moving all child components relative to the parent Actor.
-- MonsOlympus

If this is how we should use it, then we should use a SceneComponent for this example. And then we perhaps would need to change stuff? If I am toooooo bored, I'll try. Perhaps.


Update:
I tried it:

//#include "Components/ActorComponent.h"
#include "Components\SceneComponent.h"
class SHOWACTOR_API UAcRandomScaleChange : public USceneComponent//UActorComponent

After the two changes above everything compiled and linked without any problem and the result seems the same. So.. no idea.

back

(back to Unreal Engine)