繁体   English   中英

"UE4 使用具有自己参数的函数作为参数,C++"

[英]UE4 using a Function as parameter with it's own parameters, C++

我正在尝试设置一个计时器,并在 in 中使用一个函数。我阅读了计时器文档并弄清楚了它是如何工作的。 您使用 timer_handler 和要执行的函数设置计时器。 这就是问题所在。 我只能给出没有参数的函数。

GetWorldTimerManager().SetTimer(timer_handle1, this, &actor_class:Foo, 2.f, false, 1.f);

使用接收 lambda<\/a>的SetTimer<\/code>的重载。 然后使用 lambda 中的参数调用您的函数。

GetWorld()->GetTimerManager().SetTimer(
                timer_handle1,
                [&]() { this->Foo(123); },
                2.f,
                false,
                1.f);

你也可以这样做,看看这个:

用于计时器的虚幻引擎 Lambda

如果您希望某个操作仅在一个计时器或任意数量的计时器期间执行,并且您不需要保留该函数,您还可以使用 Unreal Engine 的CreateLambda 这样您就不必在您的类中专门为计时器创建任何额外的成员方法。

你可以尝试这样的事情:

void ADynamicCamera::BlendCameraInAndOut(ACharacter* InCharacter, UCharacterMovementComponent* InCharacterMovement)
{
    if (InCharacterMovement->IsWalking())
    {
        InCharacterMovement->DisableMovement();
        APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0);
        check(PlayerController);
        PlayerController->SetIgnoreLookInput(true);
        PlayerController->SetViewTargetWithBlend(this, BlendTime);
        FTimerHandle TimerHandle;
        /** The first lambda (which happens when the player steps on the TriggerBox) 
         *  can capture the Timerhandle by reference to pass it to the second lambda delegate.
         *  All other values have to be captured by value otherwise you will get a nullptr crash.
         */
        GetWorldTimerManager().SetTimer(TimerHandle, FTimerDelegate::CreateLambda([=, &TimerHandle]
        {
            check(InCharacter);
            PlayerController->SetViewTargetWithBlend(InCharacter, CameraBlendTimer);
            GetWorldTimerManager().SetTimer(TimerHandle, FTimerDelegate::CreateLambda([=]
            {
                check(InCharacterMovement && PlayerController);
                InCharacterMovement->SetMovementMode(MOVE_Walking);
                PlayerController->SetIgnoreLookInput(false);
            }), CameraBlendTimer, false);
        }), CameraBlendTimer, false);
    }
}

查看以下引擎文件夹中的DelegateSignatureImpl.inl文件,从第 139 行 (UE5) 开始,了解有关可用的不同函数委托的更多信息:

“引擎\\源\\运行时\\核心\\公共\\委托\\委托签名Impl.inl”

您还可以使用自定义 TFUNCTION 包装器来调用其他类型的委托,例如 DYNAMIC_MULTICAST_DELEGATES。 这样您就可以拥有更大的灵活性和更多的功能。 您可以像这样创建自定义包装器:

UCLASS()
class SOME_API ULambdaWrapper final : public UObject
{
    GENERATED_BODY()
public:
    TFunction<void()> CallFunction;

    UFUNCTION()
    void DelegateDispatch() { CallFunctor(); }
};

并像这样称呼他们为您的代表:

void AInGameHUD::LoadALevel(const FName& InLevelName)
{
    if (InLevelName != "")
    {
        if (LoadingScreenWidget != nullptr)
        {
            LoadingScreenWidget->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
            LoadingScreenWidget->SetFade(1.0f);
            ULambdaWrapper* LoadingScreenIsDoneFadingWrapper = NewObject<ULambdaWrapper>();
            LoadingScreenIsDoneFadingWrapper->CallFunctor = [this, InLevelName]
            {
                UGameplayStatics::OpenLevel(this, InLevelName);
            };
            LoadingScreenWidget->OnDoneFadingEvent().AddDynamic(LoadingScreenIsDoneFadingWrapper, &ULambdaWrapper::DelegateDispatch);
        }
    }
    else
    {
        UE_LOG(LogUObjectGlobals, Fatal, TEXT("Empty level name. Please add the correct level name and try again."));
    }
}

从 TFUNCTION 创建的对象旨在像标准 C++ std::function 一样使用。 那是:

  • 它们获取绑定到它们的任何内容的副本,这意味着您可以从函数中返回它们并将它们存储在对象中,而无需关心被绑定的原始对象的生命周期。 它们还可以具有任意数量的参数并具有返回类型。

从第 878 行(UE5)开始,以下引擎文件夹中的Function.h中的示例对 TFUNCTION 进行了更多说明:

"\\Engine\\Source\\Runtime\\Core\\Public\\Templates\\Function.h"

希望这有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM