Actor vs Blueprint Actor and Code Conversion

I’m making a grappling hook. I created the functionality in blueprints and am currently working on converting it to C++. Heres the code I’ve got for the section I’m having trouble with:

    //unhide cable
    m_Cable->SetHiddenInGame(false);

    //spawn transform. creates transform with default(identity) rotation and scale, then translation is set to hooked location
    FTransform SpawnTransform = FTransform::Identity;
    SpawnTransform.SetTranslation(m_HookedLoc);

    //spawn actor with transform
    m_Cable_Actor = GetWorld()->SpawnActor<AActor>(AActor::StaticClass(), SpawnTransform);

    //attach cable actor to cable component
    m_Cable_Actor->AttachToComponent(m_Cable, FAttachmentTransformRules::KeepWorldTransform);

    m_Cable_Actor->SetActorHiddenInGame(false);

This should work but the cable is invisible, so I went back to blueprints and zeroed down the only difference as being with the fact that im using a standard Actor here instead of using a blueprint Actor like the blueprint does. Why does that make any difference, and how can I change this code to work as intended?

Whether something is blueprint or not does not matter, as long as the properties are the same.

My guess is that the properties aren’t the same. When you say “invisible,” what does that mean? What’s supposed to render it? If you debug the game and inspect the spawned actor, are the rendering-related properties the same?

A visible cable is supposed to spawn and move the player towards m_HookedLoc. How would I inspect the spawned actor?

This is the blueprint I am converting from. If I swap out Cable Hooked for Actor, the cable dissapears. Nothing else changes. Cable Hooked is data-only and was created by only doing Add/Import->Blueprint Class->Actor and nothing else.

How would I inspect the spawned actor?

You play in editor, detach from the player controller with the detach button, and click the actor and look at it in the inspector window.

A visible cable is supposed to spawn

That doesn’t say anything. What is specifically supposed to render the cable? What generates the rendered mesh? What sets the material? Is that object there? Are those properties there?

I don’t know what you’re asking for. I’ve posted the relevant blueprints if that helps. I don’t really know what makes it render but I know it works fine unless I change it from an actor blueprint class (CableHooked) to a normal actor class (Actor).

[quote]unless I change it from an actor blueprint class (CableHooked) to a normal actor class (Actor).
[/quote]

I see – it’s like your blueprint derives from some class other than AActor. Your C++ class must derive from the same class to get the same behavior.

The blueprint Cable Hooked is data-only and was created by only doing Add/Import->Blueprint Class->Actor and nothing else. It should be identical to Actor. This is my confusion.

You are spawning a raw AActor instead of spawning your CableHooked blueprint class.

You need to reference/load the real blueprint class to spawn, which isn’t super straightforward in C++ because Blueprints are a layer that comes on top of C++.

For quick prototyping you can load the class by hardcoded path :

UClass* CableClass = StaticLoadClass("/Game/Blueprints/CableHooked.CableHooked_C", nullptr);
m_Cable_Actor = GetWorld()->SpawnActor<AActor>(CableClass, SpawnTransform);

The recommended way however is to do the following :

  1. declare an UClass* or TSubclassOf variable in header
UPROPERTY(EditDefaultsOnly)
TSubclassOf<AActor> CableClass;
  1. Use that variable in SpawnActor, instead of AActor::StaticClass()
  2. Create a child blueprint of your c++ actor (can be a data-only blueprint)
  3. In the BP defaults, assign the cable blueprint to the variable
  4. Make sure your game is using the BP child and not the c++ class.