Unreal4 C++ 與 藍圖(Blueprint)的簡單對照


這是第一篇有關Unreal4 中C++ 相關的文章,基本上C++ 我也是在學習中,所以有些東西可能沒辦法解釋得很好...。

本篇是我自己對於C++以及BluePrint 系統的一些疑問,如果您已經剛開始學習Unreal或者是由unity轉換過來的讀者,應該對於Unreal4 中為何使用C++,以及為何同時存在兩種不同的編程方式感到困惑。

當然Epic*(註1)這樣子做是有理由的,我目前看過最認同的部分是這篇文章:
Unreal Engine 4 基于什么考虑把 UnrealScript 替换掉而改用 C++ 开发游戏逻辑?

上面的討論其實不是本篇的重點,這篇主要對於藍圖以及c++實作一些功能上的比較,當然這篇的例子是一個很基礎得範例,目的是希望讓初學者較容易地了解兩者實作上的異同。

進入正題.....

官方C++基礎較學有個計時器效果詳細撰寫可以參考此網頁:Variables, Timers, and Events

但我增加了一些簡單功能,另外嘗試使用藍圖去實作這C++所撰寫的功能,並比較兩者的差異。 這邊是計時器的.h宣告
public: 
 // Called every frame
 virtual void Tick(float DeltaTime) override;
 //倒计时运行时长,按秒计
 UPROPERTY(EditAnywhere)
 int32 CountdownTime; //時間變數

 UPROPERTY(EditAnywhere, BlueprintReadWrite)
 FString FinalText;

 //UPROPERTY(EditAnywhere)
 UTextRenderComponent* CountdownText; //增加文字組件

 void UpdateTimerDisplay();
 
 void AdvanceTimer();

 UFUNCTION(BlueprintNativeEvent)
 void CountdownHasFinished();
 virtual void CountdownHasFinished_Implementation();//虛擬函數

 FTimerHandle CountdownTimerHandle;//時間控制器

// Sets default values//建構式
ACountdown::ACountdown()
{
  // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 PrimaryActorTick.bCanEverTick = false;
 //PrimaryActorTick.bCanEverTick = true;

 CountdownText = CreateDefaultSubobject(TEXT("CountdownNumber"));
 CountdownText->SetHorizontalAlignment(EHTA_Center);
 CountdownText->SetWorldSize(150.0f);
 CountdownText->SetTextRenderColor(FColor::Red);//自訂
 RootComponent = CountdownText;

 CountdownTime = 3;
 FinalText = FString(TEXT("This is my test FString."));;
}

// Called when the game starts or when spawned
void ACountdown::BeginPlay()
{
 Super::BeginPlay();

 UpdateTimerDisplay();
 GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);//定時器用法
 
}

// Called every frame
void ACountdown::Tick(float DeltaTime)
{
 Super::Tick(DeltaTime);

}

void ACountdown::UpdateTimerDisplay()
{
 CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
}

void ACountdown::AdvanceTimer()
{
 --CountdownTime;
 UpdateTimerDisplay();
 if (CountdownTime < 1)
 {
  //倒计时结束,停止运行定时器。
  GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
  CountdownHasFinished();
 }
}

void ACountdown::CountdownHasFinished_Implementation()
{
 //改为一个特殊的读出
 CountdownText->SetText(FinalText);
}
這是CPP主體 


在CPP的建構式中 我們設定了參數與組件的初始值 這會在此物件實體產生時直接被設定
// Sets default values//建構式
ACountdown::ACountdown()
{
  // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 PrimaryActorTick.bCanEverTick = false;
 //PrimaryActorTick.bCanEverTick = true;

 CountdownText = CreateDefaultSubobject(TEXT("CountdownNumber"));
 CountdownText->SetHorizontalAlignment(EHTA_Center);
 CountdownText->SetWorldSize(150.0f);
 CountdownText->SetTextRenderColor(FColor::Red);//自訂
 RootComponent = CountdownText;

 CountdownTime = 3;
 FinalText = FString(TEXT("This is my test FString."));;
}


 而在藍圖中也是使用建構式的部分,但是由於藍圖已經是視覺化編輯了,直接在變數宣告中設定值,在這個例子中的效果是一樣的,這部分顯得藍圖簡單許多。

 接著是遊戲開始時會執行的初始化函數跟建構式意義上是不一樣的,基本上等於於unity的Start()
void ACountdown::BeginPlay()
{
 Super::BeginPlay();

 UpdateTimerDisplay();
 GetWorldTimerManager().SetTimer(CountdownTimerHandle, this, &ACountdown::AdvanceTimer, 1.0f, true);//定時器用法
 
}


這是照做的藍圖


UpdateTimerDisplay() 函式主體:
void ACountdown::UpdateTimerDisplay()
{
 CountdownText->SetText(FString::FromInt(FMath::Max(CountdownTime, 0)));
}
藍圖對照UpdateTimerDisplay() >

AdvanceTimer()函式主體:
void ACountdown::AdvanceTimer()
{
 --CountdownTime;
 UpdateTimerDisplay();
 if (CountdownTime < 1)
 {
  //倒计时结束,停止运行定时器。
  GetWorldTimerManager().ClearTimer(CountdownTimerHandle);
  CountdownHasFinished();
 }
}
藍圖對照AdvanceTimer()

CountdownHasFinished()函式主體:
void ACountdown::CountdownHasFinished_Implementation()
{
 //改为一个特殊的读出
 CountdownText->SetText(FinalText);
}

藍圖對照CountdownHasFinished()

以上一個簡單計時器的範例 C++程式碼與藍圖的對照 

可以看出在Unreal4 藍圖系統與他的C++在遊戲邏輯上的撰寫基本上是同個東西...

這也可以看出Unreal4 藍圖系統的強大之處,原則上這樣的設計最大目的是希望讓沒有程式背景的設計師可以簡單地使用c++開發的工具是擴充或是直接使用。

兩者之間可以互相傳遞資訊,比方說可以使用C++製作出基本功能的Actor 或是Cpmponent在Unreal4 編輯器中轉換成藍圖架構 並在此之上進行擴充甚至覆寫原有的功能,要提供那些參數或是方法作為公開給藍圖使用,也可以在C++中加入Macro 標籤來管理。

實在不得不佩服這種靈活的架構,或許一開始會不太習慣,但當處理越來越複雜得功能與需求時,更能體會這種跨越時代的架構美妙之處。

關於Unreal4 C++ 與藍圖 的更深入介紹可以參考此網站:


非常詳細~

留言

這個網誌中的熱門文章

[Unreal 4]下載與安裝