Can't call a function from another class

Hello,

I am trying to figure out how to call a function from another class and I am having problems. I have the basic first person shooter tutorial open in 4.6. I followed this with no luck: How do I call a method from Another Class? - Programming & Scripting - Epic Developer Community Forums
I am trying to change the OnHit to kill an enemy class I made. Here is the code:

   void AFirstPersonProjectile::OnHit(AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
    {
    	// Only add impulse and destroy projectile if we hit a physics
    	if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL) && OtherComp->IsSimulatingPhysics())
    	{
    
    		OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation());
                    //take other actor hit and check if it is a enemy
    		FName EnemyText = "Enemy";
    		AEnemy* EnemyChar = Cast<AEnemy>(OtherActor);
    		if (EnemyChar)
    		{
    			EnemyChar->KillEnemy();
    		}

I keep getting this error though:

Error	1	error LNK2005: "public: void __cdecl AEnemy::KillEnemy(void)" (?KillEnemy@AEnemy@@QEAAXXZ) already defined in Enemy.cpp.obj	F:\Unreal4\Unreal Engine\Unreal Project\FirstPerson\Intermediate\ProjectFiles\FirstPerson.generated.cpp.obj	FirstPerson

It is saying it is already defined, but I am trying to call it so I am unsure of what is happening. I think I am using pointers wrong? Any help is appreciated!

can u post you cpp and header code of the Enemy where you define KillEnemy() here

[EDIT]

When using UFUNCTION annoations with “BlueprintNativeEvent” or similar modifiers like “Server” or “Client” the Unreal Build tool will generate the implementation of the method (in your case KillEnemy()) inside the generated header (Enemy.generated.h)

You have to implement the KillEnemy_Implementation() method inside your Enemy.cpp file.

Also checkout this Tutorial about Blueprint Native Events: C++ and Blueprints | Unreal Engine Documentation

Hope that will do the Job!

DarthB

[/EDIT]

I only consider your error message as basis for this assumption, so I may be wrong.

But do you have defined your AEnemy::KillEnemy() function inside the Enemy.h, such that you have the following Code in the Enemy files:

Enemy.h:

UCLASS()
class AEnemy : public AActor
{
  // ...
  void KillEnemy() {
    // do some stuff
  }
  //...
}

Enemy.cpp and FirstPerson.cpp:

#include "Enemy.h"
// .... more

?

If this is the case you defining the function AEnemy::KillEnemy in every translation unit that includes Enemy.h and to fix the problem you have two options:

  1. use the keyword inlne infront of your function inside the header file

    inline void KillEnemy() {
    // do some stuff
    }

  2. Move the definition into your cpp file
    Header: void KillEnemy();

    cpp:
    void AEnemy::KillEnemy() {// your code here}

More information to the topic declaration vs definition:

Have a nice day

DarthB

sure! Enemy.H:
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "Enemy.generated.h"

/**
 * 
 */
UCLASS()
class FIRSTPERSON_API AEnemy : public AActor
{
	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float fHealth;
	
	UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly)
	class USphereComponent* BaseCollisionComponent;

	UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly)
	class UStaticMeshComponent* EnemyMesh;

	UFUNCTION(BlueprintNativeEvent)
		void KillEnemy();
	
	AEnemy(const FObjectInitializer& ObjectInitializer);
};

Enemy.cpp:
// Fill out your copyright notice in the Description page of Project Settings.

#include "FirstPerson.h"
#include "Enemy.h"


AEnemy::AEnemy(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{


	BaseCollisionComponent = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(this, TEXT("BaseSphereComponent"));



	RootComponent = BaseCollisionComponent;

	//Create the static mesh component
	EnemyMesh = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("EnemyMesh"));

	EnemyMesh->SetSimulatePhysics(true);

	//attach the static mesh component to the root component
	EnemyMesh->AttachTo(RootComponent);
}

void AEnemy::KillEnemy()
{
	Destroy();

}

Hi! Thanks for the information, but I am still kinda lost. I believe I have option 2 that you mentioned going on in my code (posted .cpp and .h above) and I believe I am only declaring once, but is the way I am trying to call the function declaring again?

Hi omalleym,

the “BlueprintNativeEvent” triggers an auto code generation of the KillEnemy method inside the Enemy.generated.h (you can investigate the file but changes will be overridden by the unreal build tool)

I will edit my answer.

Hi DarthB,

Ah, my mistake! Thank you so much, was stuck for days on this. So I am assuming that if I just left it as a UFUNCTION() I would have had no problems calling the way I originally did?

Yes with an empty UFUNCTION() you would have had no problems.

Sorry, didn’t see your comment. Thank you!