iT邦幫忙

2025 iThome 鐵人賽

DAY 3
0
Software Development

30 天用 Unreal Engine 5 C++ 開發遊戲系列 第 3

# Day 3|角色類別解析 與 API 初探

  • 分享至 

  • xImage
  •  

為什麼不從頭開始?🤔

前兩天我們完成了環境設定與專案初始化。這裡有一個特別要說明的地方:
我使用的是 Unreal Engine 5.6 的 Third Person Template (C++)
和舊版不同,這個模板已經自帶了:

基礎的角色控制
簡單近戰與連擊系統
敵人 AI
基本 UI
範例地圖

幾乎涵蓋了本系列挑戰中規劃的核心要素。
所以這個 30 天挑戰的重點,不是「從零開始重造輪子」,而是 解析 → 修改 → 擴充
換句話說,這更貼近真實遊戲開發:大多時候我們都是 接手一個現有專案,然後改造成自己的遊戲

今天要做的第一步,就是來「讀懂角色類別」,尤其是角色怎麼透過 C++ 綁定輸入,讓我們能控制移動、跳躍與攻擊。

在哪裡寫我的 Code ?

專案建立後,我們要修改/新增的 Code 都在 Games\YourProjectName\Source 底下
(我的遊戲專案叫 iThome30days 所以是 Games\iThome30days\Source)

Unreal 的 C++ 有啥特別的?

在 Unreal 的 C++ 專案中,跟一般 C++ 專案一樣,每個類別通常由兩個檔案組成:

.h(Header)

  • 宣告類別:包括名稱、繼承關係、成員變數與函式介面。
  • 作用:告訴編譯器「這個類別有哪些功能」,不包含具體邏輯。

.cpp(Source)

  • 實作類別功能:撰寫函式內容、邏輯與 API 呼叫。
  • 特別之處:Unreal 在 .h 裡使用宏(Macro),例如 UCLASSUPROPERTYUFUNCTION,讓編輯器和藍圖可以識別類別及其成員。

如果參考 Unreal Engine 的 C++ 官方文件 可以學得更扎實。

📝 UE5 常用 Macro 說明

Macro 作用 用法 / 說明
UCLASS 讓 UE5 識別 C++ 類別 放在類別前面,讓編輯器能看到類別,可設置 abstractconfig 等屬性
GENERATED_BODY() 生成 UE5 需要的額外程式碼 每個 UCLASS 裡必須有,用於序列化、藍圖支援
UPROPERTY 讓變數在 UE5 可見 可設置 VisibleAnywhereEditAnywhereBlueprintReadOnly 等屬性
UFUNCTION 讓函式可在藍圖呼叫或覆寫 常用 BlueprintCallable(可在藍圖呼叫)或 BlueprintNativeEvent(可在藍圖覆寫)
FORCEINLINE 強制編譯器內聯函式 用於簡單 getter,提高效能

🔎 角色 Header 解析 iThome30dayCharacter.h

1. 前置處理與匯入

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Logging/LogMacros.h"
#include "iThome30daysCharacter.generated.h"
  • #pragma once:避免重複 include。
  • CoreMinimal.h:UE5 常用型別、Macro 的基礎標頭。
  • GameFramework/Character.h:引入 ACharacter,我們的 Class 要繼承它。
  • Logging/LogMacros.h:用來建立與使用 UE_LOG
  • generated.h:UE 反射系統必須最後 include,讓編譯器自動生成必要程式碼。

2. 前置宣告

class USpringArmComponent;
class UCameraComponent;
class UInputAction;
struct FInputActionValue;

只告訴編譯器「有這些型別存在」,不用完整 include,減少編譯依賴。

3. 日誌類別

DECLARE_LOG_CATEGORY_EXTERN(LogTemplateCharacter, Log, All);

宣告一個 log category,方便用 UE_LOG(LogTemplateCharacter, ...) 來輸出訊息。

4. 類別宣告

UCLASS(abstract)
class AiThome30daysCharacter : public ACharacter
{
	GENERATED_BODY()
        ...
  • UCLASS(abstract):讓 UE5 反射系統識別這是個類別,並標記為抽象類別(不可直接 spawn,需要子類別)。
  • GENERATED_BODY():UE 必須有,用來插入反射系統產生的程式碼。

5. 成員變數

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components", meta = (AllowPrivateAccess = "true"))
USpringArmComponent* CameraBoom;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components", meta = (AllowPrivateAccess = "true"))
UCameraComponent* FollowCamera;
  • UPROPERTY:讓變數可以被序列化、在編輯器/藍圖顯示。
  • VisibleAnywhere:只能查看,不能直接修改。
  • BlueprintReadOnly:藍圖可讀取。
  • 用途:角色的攝影機控制。

再下面還有輸入行為:

UPROPERTY(EditAnywhere, Category="Input")
UInputAction* JumpAction;
  • EditAnywhere:允許在編輯器調整。
  • 用途:綁定跳躍、移動、視角操作的輸入。

6. 建構子與輸入綁定

AiThome30daysCharacter();	
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
  • 建構子:初始化角色元件。
  • SetupPlayerInputComponent:負責把輸入動作綁定到 C++ 函式。

7. 處理輸入的函式

void Move(const FInputActionValue& Value);
void Look(const FInputActionValue& Value);
  • 將玩家輸入轉換成移動或視角操作。
UFUNCTION(BlueprintCallable, Category="Input")
virtual void DoMove(float Right, float Forward);
  • UFUNCTION(BlueprintCallable):允許藍圖呼叫。
  • DoMove / DoLook / DoJumpStart / DoJumpEnd:將輸入實際作用到角色上。

🔎 角色 Source 解析 iThome30dayCharacter.cpp

1. 角色移動

AddMovementInput(Direction, Value);
  • 來源:ACharacter
  • 功能:把玩家輸入轉成角色的移動向量

2. 跳躍

Jump();
StopJumping();
  • 來源:ACharacter
  • 功能:開始 / 停止跳躍

3. 角色旋轉控制

bUseControllerRotationYaw = false;
GetCharacterMovement()->bOrientRotationToMovement = true;
  • 控制角色是否面向移動方向

4. 相機系統

USpringArmComponent* CameraBoom;
UCameraComponent* FollowCamera;
  • CameraBoom (SpringArm) → 控制攝影機與角色距離,自動避開障礙
  • FollowCamera → 跟隨角色旋轉與移動

5. 輸入系統 (Enhanced Input)

UInputAction* MoveAction;
UInputAction* JumpAction;
UInputAction* LookAction;
  • SetupPlayerInputComponent() 配合
  • 例如:MoveAction 會呼叫 Move(),JumpAction 會呼叫 DoJumpStart()

6. BlueprintCallable 函式

UFUNCTION(BlueprintCallable)
void DoMove(float Right, float Forward);
  • 允許藍圖呼叫 C++ 函式

7. 日誌

UE_LOG(LogiThome30days, Error, TEXT("'%s' Failed to find an Enhanced Input component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this));
  • 用於 Debug

UE_LOG(日誌分類, 日誌級別(Log, Warning, Error), 輸出字串(用TEXT()包起來), ...)


今天我們快速解析了角色程式碼與 API 的核心結構,從輸入綁定到藍圖互動都有了基礎理解。

明天將進一步探討 相機 & 移動系統,包含鏡頭控制、嘗試修改 FOV,並加入衝刺功能,讓角色操控更貼近實際遊戲體驗。


上一篇
# Day 2|環境設定
下一篇
# Day 4|修改 Character Movement Component 與 Sprint 功能
系列文
30 天用 Unreal Engine 5 C++ 開發遊戲7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言