![](/img/trans.png)
[英]I am having trouble binding a sprinting action to the shift key in Unreal
[英]Why am I having trouble with polymorphism and interfaces in Unreal Engine
我一直試圖在我的游戲中進行互動,但我做錯了,我不知道在哪里。 我將在下面包含一堆代碼並省略不相關的位。
我在引擎中創建界面。 生成的 class 稱為IInteract 。 它只包含一個 function 稱為void Interact(ACharacterBase* Caller) 。 ACharacterBase只是我項目的默認 pawn。 這是 IInteract 的header文件。
#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 的 class並將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* Caller)的定義。
#include "Interactable.h"
// Sets default values
AInteractable::AInteractable()
{
}
void AInteractable::Interact(ACharacterBase* Caller)
{
Destroy();
}
我想我的第一個問題是,我應該在AInteractable和IInteract的交互 function 上的什么地方使用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 的header文件。
#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"))
}
我的第二個問題是為什么這個轉換不起作用,有沒有更好的方法在AInteractable上調用Interact(ACharacterBase* Caller) ?
謝謝您的幫助!
關於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>
。 如果 class 內部沒有虛擬表,則無法執行多態轉換,這是由virtual
方法的定義提供的( https://en.cppreference.com/w/cpp/language/object#Polymorphic_objects https://en.cppreference.com/ w/cpp/language/dynamic_cast )。
您應該將UFUNCTION(BlueprintCallable)
說明符放在 IInteract 內的IInteract
聲明上,而不是放在執行角色上。
執行者應該使用這個聲明來覆蓋:
void Interact_Implementation(ACharacterBase* Caller) override;
您不應該使用Cast
檢查 actor 是否實現了接口,而是通過調用:
actor->Implements<UInteract>()
您應該使用以下方法調用接口方法:
IInterface::Execute_Interact(someInteractable, caller)
所以你永遠不應該有理由轉換到一個接口。
此外,您還沒有驗證您的線條跟蹤是否確實擊中了AInteractable
actor。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.