I have a class that inherits from ACharacter. It has virtual functions in it, and all of those virtual functions have been implemented in its .cpp file. However, attempting to compile the project results in an error stating that there is a missing vtable in my class’s constructor. I have not written a custom destructor for the class, and the constructor takes the standard argument const FObjectInitializer& ObjectInitializer like any other C++ constructor. The constructor’s implementation does not refer to anything not found in the class declaration.
I’m absolutely puzzled as to what else could possibly be causing a missing vtable error, since the only information I’ve really been able to find is that it is usually caused by an undefined virtual member function, which does not apply here because all of my class’s virtual functions have been defined.
The header file is a modification of the ACharacter class from Tom Loman’s Survival Game template (Unreal Engine C++ Survival Game Tutorials):
#pragma once
#include "SBaseCharacter.h"
#include "SCharacter.generated.h"
class ASBombActor;
UENUM()
enum BombType
{
FireBomb,
WaterBomb,
WindBomb,
EarthBomb,
AetherBomb
};
UCLASS()
class SURVIVALGAME_API ASCharacter : public ASBaseCharacter
{
GENERATED_BODY()
ASCharacter(const FObjectInitializer& ObjectInitializer);
virtual void BeginPlay() override;
/* Called every frame */
virtual void Tick(float DeltaSeconds) override;
/* Called to bind functionality to input */
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void PawnClientRestart() override;
/* Stop playing all montages */
void StopAllAnimMontages();
float LastNoiseLoudness;
float LastMakeNoiseTime;
private:
/* Boom to handle distance to player mesh. */
UPROPERTY(VisibleAnywhere, Category = "Camera")
USpringArmComponent* CameraBoomComp;
/* Primary camera of the player*/
UPROPERTY(VisibleAnywhere, Category = "Camera")
UCameraComponent* CameraComp;
UPROPERTY(VisibleAnywhere, Category = "Camera")
class USCarryObjectComponent* CarriedObjectComp;
public:
UFUNCTION(BlueprintCallable, Category = "AI")
float GetLastNoiseLoudness();
UFUNCTION(BlueprintCallable, Category = "AI")
float GetLastMakeNoiseTime();
FORCEINLINE UCameraComponent* GetCameraComponent()
{
return CameraComp;
}
/* MakeNoise hook to trigger AI noise emitting (Loudness between 0.0-1.0) */
UFUNCTION(BlueprintCallable, Category = "AI")
void MakePawnNoise(float Loudness);
/************************************************************************/
/* Movement */
/************************************************************************/
virtual void MoveForward(float Val);
virtual void MoveRight(float Val);
/* Client mapped to Input */
void OnCrouchToggle();
/* Client mapped to Input */
void OnStartJump();
/* Client mapped to Input */
void OnStopJump();
/* Client mapped to Input */
void OnStartSprinting();
/* Client mapped to Input */
void OnStopSprinting();
virtual void SetSprinting(bool NewSprinting) override;
/* Is character currently performing a jump action. Resets on landed. */
UPROPERTY(Transient, Replicated)
bool bIsJumping;
UFUNCTION(BlueprintCallable, Category = "Movement")
bool IsInitiatedJump() const;
void SetIsJumping(bool NewJumping);
UFUNCTION(Reliable, Server, WithValidation)
void ServerSetIsJumping(bool NewJumping);
void ServerSetIsJumping_Implementation(bool NewJumping);
bool ServerSetIsJumping_Validate(bool NewJumping);
virtual void OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode = 0) override;
/************************************************************************/
/* Object Interaction */
/************************************************************************/
/* Input mapped function for carry object component */
void OnToggleCarryActor();
/* Use the usable actor currently in focus, if any */
virtual void Use();
UFUNCTION(Server, Reliable, WithValidation)
void ServerUse();
void ServerUse_Implementation();
bool ServerUse_Validate();
class ASUsableActor* GetUsableInView();
/*Max distance to use/focus on actors. */
UPROPERTY(EditDefaultsOnly, Category = "ObjectInteraction")
float MaxUseDistance;
/* True only in first frame when focused on a new usable actor. */
bool bHasNewFocus;
class ASUsableActor* FocusedUsableActor;
/************************************************************************/
/* Hunger */
/************************************************************************/
UFUNCTION(BlueprintCallable, Category = "PlayerCondition")
float GetHunger() const;
UFUNCTION(BlueprintCallable, Category = "PlayerCondition")
float GetMaxHunger() const;
UFUNCTION(BlueprintCallable, Category = "PlayerCondition")
void RestoreCondition(float HealthRestored, float HungerRestored);
/* Increments hunger, used by timer. */
void IncrementHunger();
UPROPERTY(EditDefaultsOnly, Category = "PlayerCondition")
float IncrementHungerInterval;
UPROPERTY(EditDefaultsOnly, Category = "PlayerCondition")
float IncrementHungerAmount;
/* Limit when player suffers Hitpoints from extreme hunger */
UPROPERTY(BlueprintReadOnly, Category = "PlayerCondition")
float CriticalHungerThreshold;
UPROPERTY(EditDefaultsOnly, Category = "PlayerCondition", Replicated)
float Hunger;
// Documentation Note: MaxHunger does not need to be replicated, only values that change and are displayed or used by clients should ever be replicated.
UPROPERTY(EditDefaultsOnly, Category = "PlayerCondition")
float MaxHunger;
UPROPERTY(EditDefaultsOnly, Category = "PlayerCondition")
float HungerDamagePerInterval;
/* Damage type applied when player suffers critical hunger */
UPROPERTY(EditDefaultsOnly, Category = "PlayerCondition")
TSubclassOf<UDamageType> HungerDamageType;
/************************************************************************/
/* Damage & Death */
/************************************************************************/
virtual void OnDeath(float KillingDamage, FDamageEvent const& DamageEvent, APawn* PawnInstigator, AActor* DamageCauser) override;
virtual void Suicide();
virtual void KilledBy(class APawn* EventInstigator);
/************************************************************************/
/* Bombs */
/************************************************************************/
UFUNCTION(BlueprintCallable, Category = "Bomb Material")
float GetBombMaterial() const;
UFUNCTION(BlueprintCallable, Category = "Bomb Material")
float GetMaxBombMaterial() const;
UPROPERTY(EditDefaultsOnly, Category = "Bomb Material", Replicated)
float BombMaterial;
// Documentation Note: MaxHunger does not need to be replicated, only values that change and are displayed or used by clients should ever be replicated.
UPROPERTY(EditDefaultsOnly, Category = "Bomb Material")
float MaxBombMaterial;
UPROPERTY()
TEnumAsByte<BombType> Bomb;
UPROPERTY(EditDefaultsOnly, Category = "Bomb Settings")
TSubclassOf<ASBombActor> FireBombPrototype;
UPROPERTY(EditDefaultsOnly, Category = "Bomb Settings")
TSubclassOf<ASBombActor> WaterBombPrototype;
UPROPERTY(EditDefaultsOnly, Category = "Bomb Settings")
TSubclassOf<ASBombActor> WindBombPrototype;
UPROPERTY(EditDefaultsOnly, Category = "Bomb Settings")
TSubclassOf<ASBombActor> EarthBombPrototype;
UPROPERTY(EditDefaultsOnly, Category = "Bomb Settings")
TSubclassOf<ASBombActor> AetherBombPrototype;
UFUNCTION(Server, Reliable, WithValidation)
void DropBomb();
void ServerDropBomb_Implementation();
bool ServerDropBomb_Validate();
UFUNCTION(Server, Reliable, WithValidation)
void EquipFireBomb();
void ServerEquipFireBomb_Implementation();
bool ServerEquipFireBomb_Validate();
UFUNCTION(Server, Reliable, WithValidation)
void EquipWaterBomb();
void ServerEquipWaterBomb_Implementation();
bool ServerEquipWaterBomb_Validate();
UFUNCTION(Server, Reliable, WithValidation)
void EquipWindBomb();
void ServerEquipWindBomb_Implementation();
bool ServerEquipWindBomb_Validate();
UFUNCTION(Server, Reliable, WithValidation)
void EquipEarthBomb();
void ServerEquipEarthBomb_Implementation();
bool ServerEquipEarthBomb_Validate();
UFUNCTION(Server, Reliable, WithValidation)
void EquipAetherBomb();
void ServerEquipAetherBomb_Implementation();
bool ServerEquipAetherBomb_Validate();
private:
void OnReload();
};
And this is the error in Xcode:
[6/10] Link SurvivalGame-Mac-DebugGame
Undefined symbols for architecture x86_64:
"vtable for ASCharacter", referenced from:
ASCharacter::ASCharacter(FObjectInitializer const&) in Module.SurvivalGame.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: can't open file: /Users/alonzomachiraju/Documents/Unreal Projects/EpicSurvivalGameSeries-master/LudumDare/Binaries/Mac/SurvivalGame-Mac-DebugGame.app/Contents/MacOS/SurvivalGame-Mac-DebugGame (No such file or directory)
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: can't open file: /Users/alonzomachiraju/Documents/Unreal Projects/EpicSurvivalGameSeries-master/LudumDare/Binaries/Mac/SurvivalGame-Mac-DebugGame.app/Contents/MacOS/SurvivalGame-Mac-DebugGame (No such file or directory)