UE5 C++如何获取场景组件引用并调用开门交互方法
问题
我在Unreal Engine 5用C++实现开门功能:从Sketchfab下载的门模型轴心位于中心,因此创建了Actor类ADoor1,给它添加UDoorSceneComponent作为根组件,将门Mesh挂载到该Scene Component上并调整位置,让Scene Component的轴心落在门的左下角。
已在角色类APlayerCharacter中实现Interact函数,当角色看向门并按下E键时触发;同时在UDoorSceneComponent中编写了OnInteract函数,负责将门旋转90度。当前的问题是不知道如何从角色类中调用这个OnInteract函数。
UDoorSceneComponent的OnInteract代码:
void UDoorSceneComponent::OnInteract() { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("The function is called")); FRotator NewRotation = GetRelativeRotation(); NewRotation.Yaw -= 90; SetRelativeRotation(NewRotation); }
角色类APlayerCharacter的Interact代码:
void APlayerCharacter::Interact() { FHitResult HitResult; //Makes an invisible line between the Start and End point FVector Start = FollowCamera->GetComponentLocation(); FVector End = Start + FollowCamera->GetForwardVector() * InteractLengh; // if something is between the line then it stores the information in HitResult GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECollisionChannel::ECC_Visibility); // Cast to Door. will return a nullptr if the object between Start and End wasnt the door ADoor1* DoorCast = Cast<ADoor1>(HitResult.GetActor()); // if Door exists (not a nullptr) run the open door funcion if(DoorCast) { // Got the actor refrence AActor* Door1Act = UGameplayStatics::GetActorOfClass(GetWorld(), ADoor1::StaticClass()); ADoor1* Door1Cast = Cast<ADoor1>(Door1Act); if(Door1Cast == nullptr) { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("nullptr")); } else { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("not nullptr")); } } }
补充:我在ADoor1类中添加了默认值为true的bool变量test,在角色类的Interact函数中判断该变量为true时显示调试信息,运行后能成功显示。因此确定需要获取ADoor1类中UDoorSceneComponent的引用,但不知道具体实现方法。
解决方案
步骤1:在ADoor1类中暴露UDoorSceneComponent引用
在ADoor1.h中,将UDoorSceneComponent声明为可访问的成员变量,用UPROPERTY标记让引擎识别:
// ADoor1.h #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "DoorSceneComponent.h" #include "Door1.generated.h" UCLASS() class YOURPROJECT_API ADoor1 : public AActor { GENERATED_BODY() public: ADoor1(); // 暴露DoorSceneComponent,允许外部访问 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Door") UDoorSceneComponent* DoorSceneComp; protected: virtual void BeginPlay() override; public: virtual void Tick(float DeltaTime) override; };
在ADoor1.cpp的构造函数中初始化该组件并设置为根组件:
// ADoor1.cpp #include "Door1.h" ADoor1::ADoor1() { PrimaryActorTick.bCanEverTick = true; // 创建并初始化DoorSceneComponent DoorSceneComp = CreateDefaultSubobject<UDoorSceneComponent>(TEXT("DoorSceneComp")); RootComponent = DoorSceneComp; // 此处添加门Mesh挂载到DoorSceneComp的代码(你之前的实现逻辑) }
步骤2:在角色类中调用OnInteract函数
修改角色类的Interact函数,直接通过LineTrace命中的DoorCast获取DoorSceneComp并调用OnInteract:
void APlayerCharacter::Interact() { FHitResult HitResult; FVector Start = FollowCamera->GetComponentLocation(); FVector End = Start + FollowCamera->GetForwardVector() * InteractLengh; GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECollisionChannel::ECC_Visibility); ADoor1* DoorCast = Cast<ADoor1>(HitResult.GetActor()); if(DoorCast) { // 检查DoorSceneComp是否有效,调用OnInteract if(DoorCast->DoorSceneComp) { DoorCast->DoorSceneComp->OnInteract(); GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, TEXT("调用门交互函数成功")); } else { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("门组件为空")); } } else { GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("未检测到可交互的门")); } }
关键注意事项
- 确保
UDoorSceneComponent的OnInteract函数是public权限,否则外部类无法调用:// DoorSceneComponent.h public: void OnInteract(); - 移除原代码中
UGameplayStatics::GetActorOfClass的逻辑,该方法会获取场景中第一个ADoor1实例,而非玩家实际看向的门,会导致交互逻辑错误。
内容的提问来源于stack exchange,提问作者rdex999
相关产品推荐
相关产品推荐

