1
\$\begingroup\$

I have a MovementComponent derived from CharacterMovementComponent

MovementComponent, attached to a Character, needs a reference to GrappleComponent, stored on the Character.

Where do I perform the GetComponentByClass call to obtain this reference to the GrappleComponent?

If this is the constructor, could I please have some information on how to override the constructor?

\$\endgroup\$
  • \$\begingroup\$ I think the safest would be to perform it in begin play, however it should also be ok in ConstructionScript C++ equivalent (Not constructor!) virtual void OnConstruction(const FTransform& Transform) OVERRIDE; \$\endgroup\$ – ColdSteel Oct 25 at 7:44
  • \$\begingroup\$ @ColdSteel Does the CharacterMovementComponent have a beginPlay I can override? Or am I simply overlooking the inheritance from UObject that provides this? \$\endgroup\$ – Natalo77 Oct 25 at 9:06
2
\$\begingroup\$

Normally you want to initialize default values of your member variables in the Constructor itself it will be the faster way since UE4 uses CDO, however if you want to get a reference/pointer to another component you shall do it in virtual void BeginPlay() because at the time your constructor is called the other component/actor/whatever object may not yet be initialized.

In BeginPlay you should normally have everything initialized (but, not began play yet).

Example:

In my constructor I am initializing the most common primitives:

UCNWCharacterMovementComponent::UCNWCharacterMovementComponent() //My Custom CMC constructor 
{
    m_SmoothSpeed = 5.0f;
    m_bUsesApexCloth = false;
    b_astaring = false;
    bAutoRegisterUpdatedComponent = false;

    OldVelocity = FVector::ZeroVector;

    m_rotationSpeed = 4.0f;
    m_bVisualizeMovement = true;
    m_bIsMoving = false;

}

In my BeginPlay I am getting my pointers/references to components I am about to use:

void UCNWCharacterMovementComponent::BeginPlay()
{
    Super::BeginPlay();

    SetComponentTickEnabled(false);

    //Disable Automatic Rotation!
    bOrientRotationToMovement = false;

    bIgnoreClientMovementErrorChecksAndCorrection = false;
    m_SkipFloorChecks = true;

    m_ownerRef = (ACBaseUnitCharacter*)CharacterOwner;
    if (m_ownerRef.IsValid())
    {
        m_nwAIControllerRef = Cast<ANWAIController>(m_ownerRef->Controller);
        m_desiredRotation = m_ownerRef->GetActorRotation();
    }
    TArray<AActor *> grid;
    UGameplayStatics::GetAllActorsOfClass(this, ANavigationGridActor::StaticClass(), grid);
    if(grid.Num() > 0)
    {
        m_navGridActor = (ANavigationGridActor*)grid[0];
    }

    TArray<AActor *> ObstacleProvider;
    UGameplayStatics::GetAllActorsOfClass(this, ARVO2ObstacleProvider::StaticClass(), ObstacleProvider);
    if (ObstacleProvider.Num() > 0)
    {
        m_obstacleProvider = (ARVO2ObstacleProvider*)ObstacleProvider[0];
    }

    m_unitRadius = m_ownerRef->GetCapsuleComponent()->GetScaledCapsuleRadius();
    m_unitRadiusSQ = m_unitRadius * m_unitRadius;

    MaxSimulationIterations = 100;
    m_currentSimulatedPosition = GetActorLocation();
}

Begin play will always be executed after the constructor: As you can see i do have some primetives set in BegnPlay as well but that's only because I want to be sure that they will be in these values and noone will mess them up normally you don't want the primitives to be set (unless they are dependent on actors/components (run-time created stuff)).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.