关于virtual
和override
我一直试图在游戏中进行互动,但是我做错了事,我不知道在哪里!我将在下面包含一堆代码,并省略无关的位。
我在引擎中创建界面。结果类称为IInteract。它仅包含一个称为void Interact(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)。这是AInteractable的代码。
#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 *调用者)的定义。
#include "Interactable.h"
// Sets default values
AInteractable::AInteractable()
{
}
void AInteractable::Interact(ACharacterBase* Caller)
{
Destroy();
}
我想我的第一个问题是,在AInteractable和IInteract中的交互函数上,我应该在哪里使用virtual和override关键字?
现在,我设置了键绑定,以便在按下交互键时调用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; };
我不知道为什么,但是演员表在这里失败了:
上调用Interact(ACharacterBase * Caller))>>?AActor* InteractedActor = LineTraceForward().GetActor(); IInteract* Interface = Cast<IInteract>(InteractedActor); if (Interface) { UE_LOG(LogTemp, Warning, TEXT("Cast successful")) }
我的第二个问题是,为什么这个强制转换不起作用,并且有更好的方法在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>
-我对虚幻引擎不熟悉,但是appears是某种dynamic_cast<T>
。如果没有在类中包含虚拟表的类,则无法执行多态转换,该类由virtual
方法的定义(https://en.cppreference.com/w/cpp/language/object#Polymorphic_objectshttps://en.cppreference.com/w/cpp/language/dynamic_cast)。
您应该将UFUNCTION(BlueprintCallable)
说明符放在IInteract
内的函数声明上,而不是在实现角色上。
实施者应该使用此声明覆盖:
void Interact_Implementation(ACharacterBase* Caller) override;
您不应该通过使用Cast
来检查actor是否实现了接口,而是通过调用:
actor->Implements<UInteract>()
您应使用以下方法调用接口方法:
IInterface::Execute_Interact(someInteractable, caller)
此外,您还没有验证您的行迹是否确实击中了AInteractable
演员。
关于virtual
和override
您应该将UFUNCTION(BlueprintCallable)
说明符放在IInteract
内的函数声明上,而不是在实现角色上。