You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:55:09