実装したインターフェース関数を呼び出せない。

環境
Windows10
UE5.1

やりたい事


画像の様な事をC++で実装したいです。

問題

AActor* hitActor = HitResult.GetActor();

if (Cast<IIF_Interact>(hitActor))
{
	Cast<IIF_Interact>(hitActor)->Execute_FocusOn(hitActor);
}

上記記述で実行すると
クラス IIF_Interact にメンバー Execute_FocusOn がありません
というエラーが発生します。

他ファイル

インターフェース
IF_Interact.h

UINTERFACE(MinimalAPI)
class UIF_Interact : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class CUSTOMGAME_API IIF_Interact
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	virtual void FocusOn();
};

IF_Interact.cpp

// Add default functionality here for any IIF_Interact functions that are not pure virtual.
void IIF_Interact::FocusOn() {}

実装クラス
AC_CraftingTable.h

UCLASS()
class CUSTOMGAME_API AAC_CraftingTable : public AA_BaseConstruct, public IIF_Interact
{
	GENERATED_BODY()
	
public:
	virtual void FocusOn() override;

};

AC_CraftingTable.cpp

// Add default functionality here for any IIF_Interact functions that are not pure virtual.
void IIF_Interact::FocusOn() {}

試した事
実装クラス内で実装時の関数名をFocusOn_Implementation()にしてみた。
その場合、基底クラスにそんな関数ないよと怒られました。

参考にしたサイト

上記記述で実行すると
クラス IIF_Interact にメンバー Execute_FocusOn がありません
というエラーが発生します。

その理由は、呼び出している関数がUFUNCTIONではないからです
Execute_*** は、関数がUFUNCTIONであるときに、UHTにより自動生成される BP用の 関数です

C++実装のみであれば、通常のC++関数として呼びましょう
UFUNCTIONであるときも、事前にCastするのであれば Execute_*** の方を使う必要はないです

実装クラス内で実装時の関数名をFocusOn_Implementation()にしてみた。
その場合、基底クラスにそんな関数ないよと怒られました。

こちらも同様に、UFUNCTIONかつBlueprintNativeEventである必要があります
その場合も***_Implementation の方を直接呼んではいけません
それはBPによるOverride実装を無視することになります

1 Like

ありがとうございます!
少し試してから、自身の理解踏まえて後ほどお返事します!

頂いたお返事を元に色々試して下記で動作しました!
ありがとうございます!

インターフェース
IF_Interact.h
FocusOnに緑の波線で関数定義が見つからないと出ているが動く

// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UIF_Interact : public UInterface
{
	GENERATED_BODY()
};

/**
 * 
 */
class CUSTOMGAME_API IIF_Interact
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	void FocusOn();
};

IF_Interact.cpp
前述の関数定義が見つからないエラーの為定義すると既に本体を持っている(C2084)となり実行不可

// Add default functionality here for any IIF_Interact functions that are not pure virtual.
//void IIF_Interact::FocusOn() {}

実装クラス
AAC_CraftingTable .h

UCLASS()
class CUSTOMGAME_API AAC_CraftingTable : public AA_BaseConstruct, public IIF_Interact
{
	GENERATED_BODY()
	
public:
	virtual void FocusOn_Implementation() override;

};

AAC_CraftingTable .cpp

void AAC_CraftingTable::FocusOn_Implementation()
{
	UKismetSystemLibrary::PrintString(this, "called in AAC_CraftingTable", true, true, FColor::Red, 5.0f, "None");
}

関数呼び出しクラスの一部

	GetWorld()->LineTraceSingleByObjectType(OUT HitResult, start, end, FCollisionObjectQueryParams(ECollisionChannel::ECC_WorldStatic));
	AActor* hitActor = HitResult.GetActor();
	DrawDebugLine(
		GetWorld(),
		start,
		HitResult.Location,
		FColor(255, 0, 0),
		true, -1, 0,
		12.333
	);

	if (hitActor == nullptr)
	{
		UKismetSystemLibrary::PrintString(this, "its null !!!!", true, true, FColor::Red, 5.0f, "None");
		return;
	}

	UKismetSystemLibrary::PrintString(this, "=================================", true, true, FColor::Red, 5.0f, "None");
	//Cast<IIF_Interact>(hitActor)->Execute_FocusOn(hitActor);
	bool bImpl = hitActor->GetClass()->ImplementsInterface(UIF_Interact::StaticClass());
	if (bImpl)
	{
		UKismetSystemLibrary::PrintString(this, "hit actor has Interact Interface", true, true, FColor::Red, 5.0f, "None");
    // This is calling IF Function.
		IIF_Interact:: Execute_FocusOn(hitActor);
	}
	else
	{
		UKismetSystemLibrary::PrintString(this, "No Interact Interface", true, true, FColor::Red, 5.0f, "None");
	}

実装クラスを継承したBPの子クラスでは、クラス設定の中の継承インターフェースに
IF_Interactがある事も確認できました。
image

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.