虚幻引擎 4 (ue4) 中带有自定义 c++ 蓝图函数库的蓝图循环/for/while 节点

Posted

技术标签:

【中文标题】虚幻引擎 4 (ue4) 中带有自定义 c++ 蓝图函数库的蓝图循环/for/while 节点【英文标题】:Blueprint loop/for/while node with custom c++ blueprint function library in unreal engine 4 (ue4) 【发布时间】:2020-03-01 14:57:06 【问题描述】:

我需要创建一个自定义蓝图节点。我正在使用蓝图函数库。

节点将如下所示:

输入: int timedelayforeach 循环 int 循环次数

输出: exc循环 exc完成了

loop1.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "loop1.generated.h"

/**
 * 
 */

UENUM(BlueprintType)
enum class EMultiBranchEnum1 : uint8

    BranchA,
    BranchB
;


UCLASS()
class MYPROJECT2_API Uloop1 : public UBlueprintFunctionLibrary

    GENERATED_BODY()
        UFUNCTION(BlueprintCallable, meta = (DisplayName = "loop", CompactNodeTitle = "2as2", ExpandEnumAsExecs = "Branches"), Category = "1")
        //UFUNCTION(BlueprintCallable, Meta = (DisplayName = "Multi Branch1", ExpandEnumAsExecs = "Branches"), Category = 1)
        static void multiBranch(EMultiBranchEnum1& Branches, int loopqty);
        //EMultiBranchEnum1::BranchB;

;

loop1.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "loop1.h"

void Uloop1::multiBranch(EMultiBranchEnum1& Branches, int loopqty)


    int currloop1 = 0;
    int temp = 2;
    int i;
    for (i = 0; i < 10; i++)
        currloop1 = currloop1 + 1;
        Branches = EMultiBranchEnum1::BranchA;


    

    if (temp > currloop1) 

        Branches = EMultiBranchEnum1::BranchB;
    

    if(temp == 0) 

        Branches = EMultiBranchEnum1::BranchB;

    



-- 问题-- for 循环只运行一次(从我在 branchA 上的打印节点可以看出(它只打印一次))

-- 下面的代码会发生什么-- 循环应该运行 10 次(我的打印节点应该打印 10 次)

【问题讨论】:

【参考方案1】:

您应该使用UBlueprintAsyncActionBase,而不是使用UBlueprintFunctionLibrary。它将允许您在节点中存储状态并异步调用连接到执行引脚的事物。

DelayLoop.h 文件:

#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "DelayLoop.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDelayOutputPin);

/**
 * 
 */
UCLASS()
class TEST_API UDelayLoop : public UBlueprintAsyncActionBase

    GENERATED_UCLASS_BODY()

public:
    UPROPERTY(BlueprintAssignable)
    FDelayOutputPin Loop;

    UPROPERTY(BlueprintAssignable)
    FDelayOutputPin Complete;

    UFUNCTION(BlueprintCallable, 
            meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject"), 
            Category = "Flow Control")
    static UDelayLoop* DelayLoop(const UObject* WorldContextObject, 
            const float DelayInSeconds, const int Iterations);

    virtual void Activate() override;

private:
    const UObject* WorldContextObject;
    float MyDelay;
    int MyIterations;
    bool Active;

    UFUNCTION()
    void ExecuteLoop();

    UFUNCTION()
    void ExecuteComplete();
;

DelayLoop.cpp 文件:

#include "DelayLoop.h"
#include "Engine/World.h"
#include "TimerManager.h"

UDelayLoop::UDelayLoop(const FObjectInitializer& ObjectInitializer) : 
        Super(ObjectInitializer), WorldContextObject(nullptr), MyDelay(0.0f), 
        MyIterations(0), Active(false)



UDelayLoop* UDelayLoop::DelayLoop(const UObject* WorldContextObject, 
        const float DelayInSeconds, const int Iterations)

    UDelayLoop* Node = NewObject<UDelayLoop>();
    Node->WorldContextObject = WorldContextObject;
    Node->MyDelay = DelayInSeconds;
    Node->MyIterations = Iterations;
    return Node;



void UDelayLoop::Activate()

    if (nullptr == WorldContextObject)
    
        FFrame::KismetExecutionMessage(TEXT("Invalid WorldContextObject."), 
                ELogVerbosity::Error);
        return;
    
    if (Active)
    
        FFrame::KismetExecutionMessage(TEXT("DelayLoop is already running."), 
                ELogVerbosity::Warning);
    
    if (MyDelay <= 0.0f)
    
        FFrame::KismetExecutionMessage(
                TEXT("DelayLoop delay can't be less or equal to 0."), 
                ELogVerbosity::Warning);
    
    if (MyIterations <= 0)
    
        FFrame::KismetExecutionMessage(
                TEXT("DelayLoop iterations can't be less or equal to 0."), 
                ELogVerbosity::Warning);
    

    Active = true;
    for (int i = 0; i <= MyIterations; i++)
    
        FTimerHandle IterationTimer;
        WorldContextObject->GetWorld()->GetTimerManager().SetTimer(
                IterationTimer, this, &UDelayLoop::ExecuteLoop, MyDelay * i);
    

    FTimerHandle CompleteTimer;
    WorldContextObject->GetWorld()->GetTimerManager().SetTimer(
            CompleteTimer, this, &UDelayLoop::ExecuteComplete, 
            MyDelay * (MyIterations+1));
            // If the Complete pin should happen at the same time as the last iteration
            // use `MyDelay * MyIterations` here instead



void UDelayLoop::ExecuteLoop()

    Loop.Broadcast();


void UDelayLoop::ExecuteComplete()

    Complete.Broadcast();
    Active = false;

这将为您提供如下所示的蓝图:

注意:此代码很大程度上基于 Daniel ~b617 Janowski 的 This Creating Asynchronous Blueprint Nodes guide,现在托管在旧版 wiki here

【讨论】:

以上是关于虚幻引擎 4 (ue4) 中带有自定义 c++ 蓝图函数库的蓝图循环/for/while 节点的主要内容,如果未能解决你的问题,请参考以下文章

问一下虚幻4引擎如果想自己做游戏是否很难,很耗时间?那个难学吗?我初中毕业后那一个暑假可以熟练掌

ue4 虚幻四引擎项目无法打包,求帮助!

对个人开发者虚幻4和unity哪个简单

[UE4虚幻引擎教程]-003-游戏框架的基本概念:第一个玩家控制器

UE4新手引导之下载和安装虚幻4游戏引擎

UE4新手引导之下载和安装虚幻4游戏引擎