mcpField
U
ue-cpp-foundations

ue-cpp-foundations

github.com/quodsoler開発4191.4k 回インストール4 週間前に更新
リポジトリ

ue-cpp-foundations について

Unreal Engine 5.8 の基礎的な C++ API を扱うスキルガイドです。モジュール開発者向けに、リフレクション、コンテナ、デリゲート、オブジェクトのライフタイム、サブシステムの API とコード例をまとめています。

主な機能

  1. 01リフレクションマクロとプロパティ
  2. 02コンテナとデリゲートのパターン
  3. 03文字列とオブジェクトのライフタイム
  4. 04CDO と非 null パラメーター
  5. 05エンジンサブシステムのパターン

活用シーン

  1. 01UCLASS と UPROPERTY の宣言
  2. 02UObject ポインターと GC 管理の選択
  3. 03C++ デリゲートとイベントの実装
  4. 04ゲームまたはエディターサブシステムへのアクセス

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/quodsoler/unreal-engine-skills --skill ue-cpp-foundations

インストール後、Claude Code で/ue-cpp-foundationsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
container-patterns.md
delegate-patterns.md
property-specifiers.md

詳細

UE C++ の基礎

対象エンジン:UE 5.8。以下の API は 5.8 のヘッダーで検証済みです。以前の形式は「非推奨 — 使用しないでください」に記載されています。

このスキルでは、すべての Unreal モジュールの基盤となる C++ レイヤーを扱います。リフレクションマクロ(UCLASS、UPROPERTY、UFUNCTION、USTRUCT、UENUM、UINTERFACE)、コンテナ、デリゲート、文字列型、オブジェクトのライフタイムとガベージコレクション、CDO アクセス、サブシステム群が含まれます。これらはすべて Core、CoreUObject、Engine モジュールに含まれます(PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" });)。エディターサブシステムを使用するには、エディター専用モジュールに EditorSubsystem と UnrealEd も必要です。

コンテキスト

.agents/ue-project-context.md が存在する場合は読み込んでください(モジュール名、規約、有効なプラグイン、GAS/ネットワーキングの設定)。存在しなくても作業を中断しないでください。

依頼とコードベースから対象分野を特定してください。解釈が複数あり、それぞれで異なるコードになる場合に限り、質問してください。

依頼の内容…参照先
UCLASS、UPROPERTY、UFUNCTION、USTRUCT、UENUM の指定子リフレクションマクロ
TArray、TMap、TSet、TOptional、TVariantコンテナ
デリゲート、イベント、AddDynamic、Broadcastデリゲート
FName、FString、FText、LOCTEXT文字列型
TObjectPtr、TWeakObjectPtr、TSharedPtr、GC ルート、FGCObjectオブジェクトのライフタイムとポインター
クラスデフォルトオブジェクト、GetDefault、TNotNull パラメーターCDO アクセスと非 null パラメーター
ゲームインスタンス/ワールド/ローカルプレイヤー/エンジン/エディターのサブシステムサブシステム
Replicated、ReplicatedUsing、GetLifetimeReplicatedPropsレプリケートされるプロパティ
UE_LOG、ログカテゴリロギング
WITH_EDITOR、UE_BUILD_SHIPPING ガード条件付きコンパイルガード

リフレクションマクロ

リフレクション対象の型では、ボディの最初の行に GENERATED_BODY() を置き、ヘッダーの最後の include として #include "TypeName.generated.h" を記述します。ゲームモジュール内のすべての UCLASS には、モジュール API マクロ(MYGAME_API)を付けます。指定子の解析では大文字と小文字は区別されません(エンジンのヘッダーでは config=Game と Config=Game の両方が使われています)。指定子と meta= の完全な一覧は、references/property-specifiers.md を参照してください。

UCLASS
指定子効果
Blueprintable / BlueprintTypeBlueprint でのサブクラス化/Blueprint の変数型としての使用を許可します(Not… 形式では禁止されます)
Abstractインスタンス化できません。サブクラスはインスタンス化できます
Config=Game、DefaultConfigUPROPERTY(Config) メンバーは DefaultGame.ini から読み込まれます。DefaultConfig は同ファイルへの保存も行います
Transientインスタンスは保存されません
ClassGroup=Name + meta=(BlueprintSpawnableComponent)コンポーネントが Add Component メニューに表示されます
UPROPERTY
グループ指定子
エディターでの表示EditAnywhere、EditDefaultsOnly、EditInstanceOnly、VisibleAnywhere、VisibleDefaultsOnly、VisibleInstanceOnly、AdvancedDisplay
Blueprint アクセスBlueprintReadWrite、BlueprintReadOnly、BlueprintGetter=Fn、BlueprintSetter=Fn、BlueprintAssignable(マルチキャストデリゲートのみ)
シリアライズTransient、DuplicateTransient、SaveGame、Config、GlobalConfig、Instanced、SkipSerialization、NonTransactional
レプリケーションReplicated、ReplicatedUsing=OnRep_Fn、NotReplicated
よく使われる meta= キーClampMin/ClampMax、UIMin/UIMax、EditCondition、EditConditionHides、AllowPrivateAccess、DisplayName、ToolTip、Units、AllowedClasses、MustImplement、ExposeOnSpawn、TitleProperty
// MyCharacter.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"

class UStaticMeshComponent;
class UStaticMesh;

UCLASS(Blueprintable)
class MYGAME_API AMyCharacter : public ACharacter
{
    GENERATED_BODY()
public:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats", meta=(ClampMin="1.0"))
    float MaxHealth = 100.f;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Stats")
    float CurrentHealth = 100.f;

    UPROPERTY(Transient)
    TObjectPtr<UStaticMeshComponent> CachedMesh;     // not serialized, still GC-tracked

    UPROPERTY(EditDefaultsOnly, Category="Config")
    TSubclassOf<AActor> ProjectileClass;             // class reference restricted to AActor subclasses
    UPROPERTY(EditDefaultsOnly, Category="Config")
    TSoftObjectPtr<UStaticMesh> LazyMesh;            // path reference; load on demand

    UFUNCTION(BlueprintNativeEvent, Category="Combat")
    void OnDamageTaken(float Amount);
    virtual void OnDamageTaken_Implementation(float Amount);
};
UFUNCTION
指定子効果
BlueprintCallable / BlueprintPure実行ピンあり/なしのノードです。BlueprintPure は状態を変更してはいけません
BlueprintNativeEventBlueprint でオーバーライドできます。C++ のデフォルト実装本体は Name_Implementation です
BlueprintImplementableEventBlueprint で実装します。C++ の実装本体はありません
BlueprintAuthorityOnly / BlueprintCosmeticBlueprint からの呼び出しは、ネットワーク権限がある場合のみ実行されます/専用サーバーでは実行されません(C++ から直接呼び出した場合はフィルタリングされません)
Server、Client、NetMulticast と Reliable または Unreliable、WithValidationRPC です。ルールと例については ue-networking-replication を参照してください
Execコンソールコマンドです。コンソールは PlayerInput、PlayerController、Pawn、HUD、GameMode、CheatManager、GameState、PlayerCameraManager、GameInstance にルーティングします
CallInEditorDetails パネルにボタンを追加します
// MyCharacter.cpp — the only body a BlueprintNativeEvent gets in C++
void AMyCharacter::OnDamageTaken_Implementation(float Amount) { CurrentHealth = FMath::Max(0.f, CurrentHealth - Amount); }

関数ライブラリ、潜在ノードと非同期ノード、WorldContext/DefaultToSelf/ExpandEnumAsExecs、その他の Blueprint 向け meta= キーについては、ue-blueprint-cpp-interop を参照してください。

USTRUCT、UENUM、UINTERFACE
// MyTypes.h
#pragma once
#include "CoreMinimal.h"
#include "MyTypes.generated.h"

USTRUCT(BlueprintType)
struct MYGAME_API FMyWeaponStats
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Weapon")
    float BaseDamage = 10.f;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Weapon")
    float FireRate = 0.5f;
};

UENUM(BlueprintType)
enum class EMyWeaponState : uint8      // Blueprint-visible enums are enum class : uint8
{
    Idle,
    Firing    UMETA(DisplayName="Firing Weapon"),
    MAX       UMETA(Hidden)
};
  • UDataTable の行型は、FTableRowBase(Engine/DataTable.h)を継承する USTRUCT です。ue-data-assets-tables を参照してください。
  • すべての USTRUCT メンバーをクラス内で初期化してください。リフレクション対象の構造体は値型であり、エンジンによって自由にコピーされます。
  • ポリモーフィックな構造体値(基底クラスから派生した任意の USTRUCT)は、FInstancedStruct または型付きの TInstancedStruct<FMyBase>(StructUtils/InstancedStruct.h、モジュール CoreUObject)として格納します。
  • UINTERFACE は、UInterface を継承するスタブ UMyThing と IMyThing クラスを組み合わせます。指定子の表とネイティブの例は references/property-specifiers.md にあります。Blueprint で実装可能なインターフェースについては、ue-blueprint-cpp-interop を参照してください。

コンテナ

API 全般、反復処理、パフォーマンスに関する注意事項については、references/container-patterns.md を参照してください。UObject ポインターを格納するコンテナが GC の追跡対象になるのは、UPROPERTY() TArray<TObjectPtr<T>> の場合のみです(TMap/TSet も同様)。

TArray<FString> Names;
Names.Add(TEXT("Alpha"));
Names.Emplace(TEXT("Beta"));                       // construct in place
Names.Reserve(100);                                // pre-size before a known number of Adds
int32 Idx = Names.Find(TEXT("Beta"));              // INDEX_NONE if absent
FString* Ptr = Names.FindByPredicate([](const FString& S) { return S.StartsWith(TEXT("A")); });
Names.Sort([](const FString& A, const FString& B) { return A.Len() < B.Len(); });
Names.Remove(TEXT("Alpha"));                       // order-preserving, O(n)
Names.RemoveAtSwap(0);                             // O(1), reorders
for (int32 i = Names.Num() - 1; i >= 0; --i) { if (Names[i].IsEmpty()) { Names.RemoveAt(i); } }  // never mutate inside ranged-for

TMap<FName, int32> ItemCounts;
int32& Count = ItemCounts.FindOrAdd(FName("Sword"));  // inserts default if absent
int32* Found = ItemCounts.Find(FName("Axe"));         // nullptr if absent
for (const TPair<FName, int32>& Pair : ItemCounts) { UE_LOG(LogMyGame, Log, TEXT("%s x%d"), *Pair.Key.ToString(), Pair.Value); }

TSet<FName> Tags;
Tags.Add(FName("Flying"));
bool bFlying = Tags.Contains(FName("Flying"));     // hashed, no duplicates

TOptional<float> MaybeHP;
float Safe = MaybeHP.Get(0.f);                     // default when unset
TVariant
#include "Misc/TVariant.h"
#include <type_traits>

TVariant<int32, float, FString> Value;             // first type must be default-constructible (or use FEmptyVariantState)
Value.Set<FString>(TEXT("Hello"));
if (const FString* Str = Value.TryGet<FString>()) { UE_LOG(LogMyGame, Log, TEXT("%s"), **Str); }

Visit([](auto& Held)                               // one generic lambda; branch with if constexpr
{
    using HeldType = std::decay_t<decltype(Held)>;
    if constexpr (std::is_same_v<HeldType, FString>) { UE_LOG(LogMyGame, Log, TEXT("%s"), *Held); }
}, Value);

デリゲート

宣言マクロ、バインドメソッド、ペイロードのルールについては、references/delegate-patterns.md を参照してください。

マクロファミリーバインディング数Blueprint用途
DECLARE_DELEGATE(_RetVal、_OneParam …)1いいえ単一オーナーのコールバック。値を返すこともできます
DECLARE_MULTICAST_DELEGATENいいえC++ イベント(別スレッド用には DECLARE_TS_…)
DECLARE_DYNAMIC_DELEGATE1はいBlueprint に割り当て可能なコールバック(UFUNCTION ターゲットのみ)
DECLARE_DYNAMIC_MULTICAST_DELEGATENはいUPROPERTY(BlueprintAssignable) イベント
// MyHealthComponent.h — delegate types are declared at file scope, above the UCLASS
DECLARE_MULTICAST_DELEGATE_TwoParams(FOnMyHealthChangedNative, float /*Current*/, float /*Max*/);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMyHealthChanged, float, CurrentHealth, float, MaxHealth);

// in UMyHealthComponent : public UActorComponent
UPROPERTY(BlueprintAssignable, Category="Health")
FOnMyHealthChanged OnHealthChanged;               // dynamic: needs UPROPERTY, params need names
FOnMyHealthChangedNative OnHealthChangedNative;   // native: no reflection, cheaper to broadcast

// in AMyListenerActor : public AActor
UFUNCTION()                                       // AddDynamic targets must be UFUNCTIONs
void HandleHealthChanged(float CurrentHealth, float MaxHealth);
void HandleHealthChangedNative(float Current, float Max);
UPROPERTY() TObjectPtr<UMyHealthComponent> Health;
FDelegateHandle NativeHandle;
// AMyListenerActor.cpp — bind in BeginPlay (after Super::), unbind in EndPlay (before Super::)
Health->OnHealthChanged.AddDynamic(this, &AMyListenerActor::HandleHealthChanged);
NativeHandle = Health->OnHealthChangedNative.AddUObject(this, &AMyListenerActor::HandleHealthChangedNative);
// EndPlay: guard with IsValid(Health) first
Health->OnHealthChanged.RemoveDynamic(this, &AMyListenerActor::HandleHealthChanged);
Health->OnHealthChangedNative.Remove(NativeHandle);

オーナーは OnHealthChanged.Broadcast(CurrentHealth, MaxHealth); でブロードキャストします。両方のクラス全体は、references/delegate-patterns.md を参照してください。

単一デリゲートは BindUObject、BindSP、BindRaw、BindStatic、BindLambda、BindWeakLambda(this, ...) でバインドし、ExecuteIfBound(...) で実行します。this をキャプチャするラムダには、オブジェクトとともにバインディングが破棄されるよう、AddWeakLambda/BindWeakLambda を優先してください。

文字列型

型用途比較備考
FName識別子、アセット名、ボーン名、タグ整数による O(1)、大文字と小文字を区別しないグローバルテーブルにインターン化されます。不変です
FStringパス、解析、実行時に生成するテキストO(n)可変のヒープ文字列です。*Str は const TCHAR* を返します
FTextプレイヤーが読むすべてのテキスト—ローカライズ可能です。LOCTEXT/NSLOCTEXT/FText::Format で構築します
float Health = 42.f; int32 Current = 3; int32 Max = 5;

FName   Tag(TEXT("Weapon.Rifle"));
FString S    = Tag.ToString();
FName   Back = FName(*S);
FString Msg  = FString::Printf(TEXT("HP: %.1f (%d/%d)"), Health, Current, Max);
int32 Parsed = FCString::Atoi(TEXT("42"));

#define LOCTEXT_NAMESPACE "MyGame"
FText Label = LOCTEXT("RifleName", "Assault Rifle");
FText Fmt   = FText::Format(LOCTEXT("HPFmt", "HP: {0}/{1}"), FText::AsNumber(Current), FText::AsNumber(Max));
#undef LOCTEXT_NAMESPACE
FText Other = NSLOCTEXT("MyGame", "Key", "Text");   // no #define needed
FText Raw   = FText::FromString(S);                 // not localized; runtime-generated text only

オブジェクトのライフタイムとポインター

ガベージコレクターは、ルートからリフレクションされた(UPROPERTY)参照、FGCObject の参照元、TStrongObjectPtr、およびルート化されたオブジェクトを通じて到達可能なすべての UObject を生存状態に保ちます。GC から見えないポインターは、ダングリングする可能性があります。

// Reflected members: TObjectPtr — GC-tracked, access-tracked in the editor, used like a raw pointer
UPROPERTY() TObjectPtr<UStaticMeshComponent> MeshComp;

// Legacy APIs that want raw pointers
void FillObjects(TArray<UObject*>& Out);
TArray<TObjectPtr<UObject>> Objects;
FillObjects(MutableView(Objects));                       // temporary TArray<UObject*>& view; ToRawPtr(Ptr) for a single read-only copy

// Non-owning reference: TWeakObjectPtr becomes null once the object is destroyed or collected
TWeakObjectPtr<AMyCharacter> WeakTarget;
if (AMyCharacter* Target = WeakTarget.Get()) { Target->OnDamageTaken(5.f); }

// Keep-alive from non-reflected code: scoped root instead of AddToRoot()/RemoveFromRoot()
TStrongObjectPtr<UMyDataObject> Pinned(NewObject<UMyDataObject>());

// Plain C++ types only: never wrap a UObject in TSharedPtr/TUniquePtr
struct FMyData { int32 Score = 0; };
TSharedPtr<FMyData> Data = MakeShared<FMyData>();
TWeakPtr<FMyData>   WeakData = Data;                     // Pin() returns a TSharedPtr if still alive

UObject を保持する UObject 以外のクラスは FGCObject を継承し、TObjectPtr メンバーを通じてそれらを報告します。AddReferencedObject(s) の生の UObject* オーバーロードは非推奨であり、インクリメンタル GC では安全ではありません。

#include "UObject/GCObject.h"

class FMyManager : public FGCObject
{
public:
    virtual void AddReferencedObjects(FReferenceCollector& Collector) override { Collector.AddReferencedObject(ManagedObject); }
    virtual FString GetReferencerName() const override { return TEXT("FMyManager"); }
private:
    TObjectPtr<UMyDataObject> ManagedObject;   // TObjectPtr<T>& overload; raw UObject* is deprecated
};

CDO アクセスと非 null パラメーター

#include "Misc/NotNull.h"

const UMyDataObject* Defaults = GetDefault<UMyDataObject>();        // class default object, read-only
UMyDataObject*       Settings = GetMutableDefault<UMyDataObject>(); // settings-style objects
UClass* SomeClass = AMyCharacter::StaticClass();
const AMyCharacter* ClassCDO = SomeClass->GetDefaultObject<AMyCharacter>();  // CDO of a runtime UClass

// TNotNull<T*>: caller cannot pass null; checked at the call site in Debug/Development, a plain pointer in Test and Shipping
void RegisterOwner(TNotNull<AActor*> Owner);
void RegisterOwner(TNotNull<AActor*> Owner)
{
    Owner->SetActorHiddenInGame(false);   // no null check needed inside
}

UClass::ClassDefaultObject の直接アクセスは非推奨です。TNotNull<T*> は暗黙的に T* に変換されます。null が意味のある値である場合は、T* を使用してください。

サブシステム

エンジンオブジェクトが所有する、自動インスタンス化されるシングルトンです。手動でルート化する必要はありません。Initialize(FSubsystemCollectionBase&)/Deinitialize() をオーバーライドします。順序が重要な場合は、Initialize 内で Collection.InitializeDependency<UMyOtherSubsystem>() を呼び出します。対象外にするには、ShouldCreateSubsystem(UObject* Outer) const から false を返します。

クラスヘッダー所有者/ライフタイムアクセサー
UEngineSubsystemSubsystems/EngineSubsystem.hUEngine;プロセス全体GEngine->GetEngineSubsystem<T>()
UGameInstanceSubsystemSubsystems/GameInstanceSubsystem.hUGameInstance;マップ変更後も存続GetGameInstance()->GetSubsystem<T>()
UWorldSubsystemSubsystems/WorldSubsystem.hUWorld;ワールドごとに再作成されます。DoesSupportWorldType でフィルタリングしますGetWorld()->GetSubsystem<T>()
UTickableWorldSubsystemSubsystems/WorldSubsystem.h上記に加えて Tick() を実行します。GetStatId() の実装が必要ですGetWorld()->GetSubsystem<T>()
ULocalPlayerSubsystemSubsystems/LocalPlayerSubsystem.hULocalPlayer;ローカルプレイヤーごとに 1 つLocalPlayer->GetSubsystem<T>()、ULocalPlayer::GetSubsystemFromController<T>(PC)
UEditorSubsystemEditorSubsystem.h(モジュール EditorSubsystem)UEditorEngine;エディターセッション中のみGEditor->GetEditorSubsystem<T>()
// MyInventorySubsystem.h
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "MyInventorySubsystem.generated.h"

UCLASS()
class MYGAME_API UMyInventorySubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()
public:
    virtual void Initialize(FSubsystemCollectionBase& Collection) override;
    virtual void Deinitialize() override;

    UFUNCTION(BlueprintCallable, Category="Inventory")
    void AddItem(FName ItemID, int32 Count);
private:
    TMap<FName, int32> Inventory;
};

// A ticking world subsystem adds these; Initialize/Deinitialize must call Super:: (the base registers the ticker)
UCLASS()
class MYGAME_API UMyTickableSubsystem : public UTickableWorldSubsystem
{
    GENERATED_BODY()
public:
    virtual void Tick(float DeltaTime) override;
    virtual TStatId GetStatId() const override { RETURN_QUICK_DECLARE_CYCLE_STAT(UMyTickableSubsystem, STATGROUP_Tickables); }
    virtual bool DoesSupportWorldType(const EWorldType::Type WorldType) const override;  // e.g. Game and PIE only
};
// Access from an AActor member function
UMyInventorySubsystem* Inv = GetGameInstance()->GetSubsystem<UMyInventorySubsystem>();
UMyTickableSubsystem*  Tck = GetWorld()->GetSubsystem<UMyTickableSubsystem>();
APlayerController*     PC  = GetWorld()->GetFirstPlayerController();
UMyUISubsystem*        UI  = ULocalPlayer::GetSubsystemFromController<UMyUISubsystem>(PC);   // null-safe
UMyEngineSubsystem*    Eng = GEngine->GetEngineSubsystem<UMyEngineSubsystem>();

UWorldSubsystem では、PostInitialize()、OnWorldBeginPlay(UWorld& InWorld)、OnWorldEndPlay(UWorld& InWorld)、OnWorldComponentsUpdated(UWorld& World) もオーバーライドできます。ULocalPlayerSubsystem::GetLocalPlayer<T>() と UGameInstanceSubsystem::GetGameInstance() は所有者を返します。

レプリケートされるプロパティ

指定子と GetLifetimeReplicatedProps のエントリーの両方が必要です。条件(COND_*)、RPC のルール、プッシュモデル、Iris については、ue-networking-replication を参照してください。

// MyReplicatedActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyReplicatedActor.generated.h"

UCLASS()
class MYGAME_API AMyReplicatedActor : public AActor
{
    GENERATED_BODY()
public:
    AMyReplicatedActor() { bReplicates = true; }
    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
protected:
    UPROPERTY(ReplicatedUsing=OnRep_Health)
    float Health = 100.f;

    UFUNCTION()
    void OnRep_Health();                 // runs on clients after Health changes
};
// MyReplicatedActor.cpp
#include "MyReplicatedActor.h"
#include "Net/UnrealNetwork.h"          // required for DOREPLIFETIME

void AMyReplicatedActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    DOREPLIFETIME(AMyReplicatedActor, Health);
}

void AMyReplicatedActor::OnRep_Health() {}

ロギング

DECLARE_LOG_CATEGORY_EXTERN(LogMyGame, Log, All);   // MyGame.h (module header)
DEFINE_LOG_CATEGORY(LogMyGame);                     // MyGame.cpp
UE_LOG(LogMyGame, Warning, TEXT("HP low: %.1f"), 12.5f);

詳細度(Logging/LogVerbosity.h):Fatal、Error、Warning、Display、Log、Verbose、VeryVerbose。Display はコンソールとログファイルに出力し、Log はログファイルのみに出力します。Shipping ビルドでは、ターゲットで bUseLoggingInShipping = true を設定しない限り、UE_LOG はコンパイル時に除外されます。カテゴリ、構造化ロギング(UE_LOGFMT)、実行時の詳細度制御、プロファイリングについては、ue-testing-debugging を参照してください。

条件付きコンパイルガード

#if WITH_EDITORONLY_DATA
    UPROPERTY(EditAnywhere, Category="Debug")
    bool bShowDebugSpheres = false;                 // reflected editor-only data
#endif
#if WITH_EDITOR
    virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;   // editor-only code
#endif
#if !UE_BUILD_SHIPPING
    void DrawDebugInfo();                           // Debug, Development and Test only
#endif

非推奨 — 使用しないでください

使用しない5.8 で使用出典
SomeClass->ClassDefaultObjectGetDefault<T>()、GetMutableDefault<T>()、SomeClass->GetDefaultObject<T>()UObject/Class.h:4045 の UE_DEPRECATED(5.6)
UObject* メンバーでの Collector.AddReferencedObject(RawUObjectPtr)AddReferencedObject(s) に渡す TObjectPtr<T> メンバーUObject/UObjectGlobals.h:109 の UE_REFERENCE_COLLECTOR_REQUIRE_OBJECTPTR_DEPRECATED による UE_DEPRECATED(5.3)
可変配列での ToRawPtrArrayUnsafe(Array)、ToRawPtrTArrayUnsafe(Array)MutableView(Array)、または TArray<TObjectPtr<T>> のままにするUObject/ObjectPtr.h:1112,1156 の UE_DEPRECATED(5.6)
Visit(<overload-set helper struct>{...}, Variant)if constexpr (std::is_same_v<...>) を使った単一のジェネリックラムダヘルパーは Lyra のサンプルコードであり、5.8 のヘッダーにはありません(Misc/TVariant.h)
GENERATED_USTRUCT_BODY()、GENERATED_UCLASS_BODY()、GENERATED_IINTERFACE_BODY()GENERATED_BODY()UObject/ObjectMacros.h:802-805 のレガシーエイリアス
一時的な生存維持のための Obj->AddToRoot()/RemoveFromRoot()TStrongObjectPtr<T>(UObject/StrongObjectPtr.h)Root 登録は解除されるまで永続します。スコープ付きポインターならリークしません
TMap::TIterator(Map, /*bRequiresRehashOnRemoval*/ true)(削除後に自動で Relax)Map.CreateIterator()。必要に応じて、自分で Compact()/Shrink() を呼び出しますContainers/Map.h.inl:916 の UE_DEPRECATED(5.8)。TSet::Relax() 自体にはまだマークされていません(Containers/SparseSet.h.inl:319)
TIsConst<T>、TIsMemberPointer<T>std::is_const_v<T>、std::is_member_pointer_v<T>Templates/IsConst.h:15 の UE_DEPRECATED(5.7)、Templates/IsMemberPointer.h:14 の UE_DEPRECATED(5.8)
FThreadSafeRefCountedObject、FRefCountBaseFRefCountedObject(現在はスレッドセーフ)Templates/RefCounting.h:151-153 の UE_DEPRECATED(5.8)
FCoreDelegates::OnPostEngineInit.AddRaw(...)FCoreDelegates::GetOnPostEngineInit().AddRaw(...)Misc/CoreDelegates.h:240 の UE_DEPRECATED(5.8)
Delegate.ProcessMulticastDelegate<UObject>(Params)Delegate.ProcessDelegate<UObject>(Params)UObject/ScriptDelegates.h:1462 の UE_DEPRECATED(5.8)
meta=(HideAssetPicker)meta=(HidePinAssetPicker)UObject/ObjectMacros.h:1673 の UE_DEPRECATED(5.6)
ObjPtr.IsRemote()ObjPtr.GetResidence()UObject/ObjectPtr.h:206 の UE_DEPRECATED(5.8)

よくある間違い

UPROPERTY のない生の UObject* メンバー — GC 後にダングリングします:

UMyDataObject* Obj;                        // WRONG: invisible to GC
UPROPERTY() TObjectPtr<UMyDataObject> Obj; // RIGHT

範囲ベースの for ループ内で TArray を変更する — イテレーターが無効になります:

TArray<AActor*> Actors;
for (AActor* A : Actors) { Actors.Remove(A); }                                                      // WRONG
for (int32 i = Actors.Num() - 1; i >= 0; --i) { if (!IsValid(Actors[i])) { Actors.RemoveAt(i); } }  // RIGHT

UObject を TSharedPtr でラップする — 所有者が二つになり、クラッシュします: UObject は GC が所有します。TObjectPtr、TWeakObjectPtr、または TStrongObjectPtr を使用してください。

.generated.h が最後のインクルードではない、または MYGAME_API がない: UnrealHeaderTool がヘッダーを拒否します。API マクロがないと、後に別のモジュールから LNK2019 が発生します。

非 UFUNCTION にバインドされた AddDynamic: リフレクション検索が実行時に失敗し、ハンドラーが実行されません。UFUNCTION() を付けてください。

.cpp の定義の上に UPROPERTY/UFUNCTION を記述する: UnrealHeaderTool が解析するのはヘッダーだけなので、マクロは無視されます。クラス本体内の宣言に付けてください。

Name_Implementation のない BlueprintNativeEvent: リンク時に未解決の外部シンボルになります。virtual void Name_Implementation(...) を宣言して定義してください。

Super:: を呼び出さない UTickableWorldSubsystem::Initialize/Deinitialize のオーバーライド: ティック登録は基底クラスの実装内にあります。サブシステムはティックされません。

ClassDefaultObject を直接読み取る: 非推奨であり、まもなく private になります。GetDefault<T>() を使用してください。

Log の詳細度が「表示されない」: Log は仕様上ファイルにのみ出力されます。コンソールに出力するには Display を使用してください。

関連するスキル

  • ue-actor-component-architecture — AActor/UActorComponent のライフサイクル、スポーン、ティックグループ、コンポーネントのセットアップ
  • ue-module-build-system — Build.cs、モジュールの依存関係、API エクスポートマクロ、インクルードパス、PCH
  • ue-testing-debugging — ログカテゴリと詳細度、構造化ログ、オートメーションテスト、プロファイリング
  • ue-networking-replication — DOREPLIFETIME の条件、RPC のルール、プッシュモデル、Iris
  • ue-blueprint-cpp-interop — UBlueprintFunctionLibrary、潜在アクションと非同期アクション、Blueprint で実装可能
  • 関連項目:ue-data-assets-tables、ue-animation-system、ue-async-threading、ue-audio-system、ue-editor-tools、ue-gameplay-abilities、ue-gameplay-framework、ue-gameplay-tags-messaging、ue-input-system、ue-mass-entity、ue-materials-rendering、ue-serialization-savegames、ue-state-trees、ue-ui-umg-slate、ue-world-level-streaming

コメント