为什么我在虚幻引擎中的多态性和接口方面遇到问题?
Why am I having trouble with polymorphism and interfaces in Unreal Engine
我一直在尝试在我的游戏中进行交互,但我做错了什么,我不知道在哪里!我将在下面包含一堆代码并省略不相关的位。
我在引擎中创建接口。生成的类称为IInteract。它只包含一个名为voidInteract(ACharacterBase* Caller(的函数。ACharacterBase只是我项目的默认棋子。这是IInteract的头文件。
#pragma once
#include "STRGZR/Characters/CharacterBase.h"
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "Interact.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UInteract : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class STRGZR_API IInteract
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
void Interact(ACharacterBase* Caller);
};
现在,我创建了另一个名为AInteractable的类,并将IInteract实现到AInteractable中。然后我从接口声明了 Interact(ACharacterBase* Caller(。这是AInteracable的代码。
#pragma once
#include "Interact.h"
#include "STRGZR/Characters/CharacterBase.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Interactable.generated.h"
UCLASS()
class STRGZR_API AInteractable : public AActor, public IInteract
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AInteractable();
protected:
UFUNCTION(BlueprintCallable)
void Interact(ACharacterBase* Caller);
public:
};
这是void Interact(ACharacterBase* Caller(的定义。
#include "Interactable.h"
// Sets default values
AInteractable::AInteractable()
{
}
void AInteractable::Interact(ACharacterBase* Caller)
{
Destroy();
}
我想我的第一个问题是,我应该在哪里使用虚拟和覆盖AInteractable和IInteract中交互函数的关键字?
现在,我设置了键绑定,以便在按下交互键时调用ACharacterBase中的OnInteract。这是ACharacterBase的代码文件。
#include "GameFramework/CharacterMovementComponent.h"
#include "STRGZR/Interactable/Interact.h"
#include "CharacterBase.h"
// Sets default values
ACharacterBase::ACharacterBase()
{
LineTraceLength = 2000.f;
}
// Called to bind functionality to input
void ACharacterBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up gameplay key bindings
check(PlayerInputComponent);
// Bind Interact event
PlayerInputComponent->BindAction("Interact", IE_Pressed, this, &ACharacterBase::OnInteract);
}
FHitResult ACharacterBase::LineTraceForward()
{
FHitResult HitResult;
FCollisionQueryParams CollisionQueryParams;
FVector CharacterLocation;
FRotator CharacterRotation;
GetActorEyesViewPoint(CharacterLocation, CharacterRotation);
FVector Start = CharacterLocation;
FVector End = CharacterLocation + (CharacterRotation.Vector() * LineTraceLength);
ActorLineTraceSingle(HitResult, Start, End, ECC_Visibility, CollisionQueryParams);
return HitResult;
}
void ACharacterBase::OnInteract()
{
AActor* InteractedActor = LineTraceForward().GetActor();
IInteract* Interface = Cast<IInteract>(InteractedActor);
if (Interface)
{
UE_LOG(LogTemp, Warning, TEXT("Cast successful"))
}
}
这也是ACharacterBase的头文件。
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CharacterBase.generated.h"
UCLASS()
class STRGZR_API ACharacterBase : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ACharacterBase();
protected:
UFUNCTION(BlueprintCallable, Category = "Interaction")
FHitResult LineTraceForward();
UFUNCTION(BlueprintCallable, Category = "Input")
void OnInteract();
public:
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
我不知道为什么,但演员阵容在这里失败了:
AActor* InteractedActor = LineTraceForward().GetActor();
IInteract* Interface = Cast<IInteract>(InteractedActor);
if (Interface)
{
UE_LOG(LogTemp, Warning, TEXT("Cast successful"))
}
我的第二个问题是为什么这个转换不起作用,有没有更好的方法来调用Interact(ACharacterBase* Caller(在AInteractable上?
感谢您的帮助!
关于virtual
和override
以下是动态多态性的基本用法:
class IInterface {
public:
virtual void method() = 0;
};
class CClass : public IInterface {
public:
void method() override { // do smth }
};
int main() {
IInterface* ptr = new CClass();
ptr->method();
}
(不要忘记删除 ptr 或使用引用计数(
您可以在此处阅读有关虚拟方法的信息:
https://en.cppreference.com/w/cpp/language/virtual
https://en.cppreference.com/w/cpp/language/override
至于Cast<T>
- 我不熟悉虚幻引擎,但它似乎是某种dynamic_cast<T>
。如果没有类内部具有虚拟表,则无法执行多态转换,这是由virtual
方法的定义提供的 (https://en.cppreference.com/w/cpp/language/object#Polymorphic_objects https://en.cppreference.com/w/cpp/language/dynamic_cast(。
-
你应该把
UFUNCTION(BlueprintCallable)
说明符放在IInteract
里面的函数声明上,而不是在实现的参与者上。 -
实现参与者应使用以下声明进行重写:
void Interact_Implementation(ACharacterBase* Caller) override;
-
您不应该通过使用
Cast
来检查参与者是否实现接口,而是通过调用:actor->Implements<UInteract>()
-
应使用以下方法调用接口方法:
IInterface::Execute_Interact(someInteractable, caller)
因此,您永远不应该有理由投射到接口。
此外,您尚未验证您的线路跟踪是否确实击中了AInteractable
演员。
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- Visual C++GC接口如何启用它以及要包含哪个库
- Windows.h与GLFW.h的接口
- GCC和Clang在与__builtin_constant_p相关的static_assert方面有所不同
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 提供与TMP和SFINAE的通用接口
- 为重写std::exception的库生成swig接口时出错
- 内联如何影响模块接口中的成员函数
- COM 接口 c# 封送数组数组
- 如何在 SCIP C++ 接口中获取 MILP 约束矩阵中的系数值
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如何绑定 C++ gRPC 客户端的网络接口
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何从实现接口的模板化类实例访问结构
- 带有进度表的 curl 多接口程序
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 我可以在具有一个标头和一个接口的 cpp 文件中有多个嵌入吗?
- 类接口,可以创建N个方法
- 为什么我在虚幻引擎中的多态性和接口方面遇到问题?
- 在 Windows 上的环回接口上使用 tcp/ip 的延迟方面可以预期的情况