笔记

取消Win11的右键菜单展示更多选项

管理员权限运行Cmd输入下面指令

Cmd
1
reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve

禁用VSCode的预览模式

打开 VSCode 设置:按下Ctrl +,(Windows/Linux)或 Cmd + ,(Mac)。
搜索 workbench.editor.enablePreview。
取消勾选此选项(或设置为 false)。

加快UE的Editor启动和游戏启动

1
wp.CrashSight.MatrixMemoryStatEnableWin=False

UE的Cursor Rules

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 虚幻引擎C++代码风格规则

## 文件结构规则

1. 所有头文件使用`#pragma once`
2. 包含顺序:
- 核心虚幻头文件(CoreMinimal.h)
- 本类头文件
- 引擎相关头文件
- 项目头文件
- 生成的头文件(*.generated.h)

## 命名规则

1. 类前缀:
- `U` - UObject派生类
- `A` - Actor派生类
- `F` - 结构体和非UObject类
- `I` - 接口
- `E` - 枚举

2. 函数命名:
- 公有函数: Pascal命名法(如`GetHealth()`)
- 事件处理函数: 以`Handle`开头(如`HandleButtonClicked()`)

3. 变量命名:
- 成员变量: 驼峰命名法,首字母大写
- 局部变量: 驼峰命名法,首字母小写
- 布尔变量: 使用`b`前缀(如`bIsVisible`)

4. 类型别名命名:
- 使用`F`前缀表示类型别名(如`FCategoryMap`)
- 类型别名应当具有描述性,表明其用途

5. 委托命名:
- 使用`F`前缀表示委托类型(如`FOnItemClickedEvent`)
- 委托实例使用描述性名称(如`OnButtonClicked`)

## 类结构规则

1. 类内成员排序:

GENERATED_BODY()

类型别名定义 (using或typedef)

// 变量部分 (从private到public)
private:
// 非UPROPERTY变量
<非UPROPERTY标记的变量>

   // UPROPERTY变量
   UPROPERTY(...)
   <UPROPERTY标记的变量>

protected:
// 非UPROPERTY变量
<非UPROPERTY标记的变量>

   // UPROPERTY变量
   UPROPERTY(...)
   <UPROPERTY标记的变量>

public:
// 非UPROPERTY变量
<非UPROPERTY标记的变量>

   // UPROPERTY变量
   UPROPERTY(...)
   <UPROPERTY标记的变量>

// 函数部分 (从public到private)
public:
// 构造函数和析构函数
<构造函数和析构函数>

   // UFUNCTION函数
   UFUNCTION(...)
   <UFUNCTION标记的函数>

   // 虚函数重写
   virtual void Function() override;

   // 普通函数
   <非虚函数且非UFUNCTION的函数>

protected:
// UFUNCTION函数
UFUNCTION(…)
<UFUNCTION标记的函数>

   // 虚函数重写
   virtual void Function() override;

   // 普通函数
   <非虚函数且非UFUNCTION的函数>

private:
// UFUNCTION函数
UFUNCTION(…)
<UFUNCTION标记的函数>

   // 虚函数重写
   virtual void Function() override;

   // 普通函数
   <非虚函数且非UFUNCTION的函数>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

2. 类型别名定义:
- 复杂类型应使用typedef或using定义别名
- 以下类型必须定义别名:
- 复杂的嵌套模板类型(如`TMap<FName, TArray<FConfig>>`)
- 过长无法与其他变量对齐的类型(如`TMap<FName, TSharedPtr<SComplexWidget>>`)
- 类型别名应放在GENERATED_BODY()下面
- 类型别名的名称与赋值符号(=)之间应对齐
```cpp
UCLASS()
class EXAMPLE_API UMyClass : public UObject
{
GENERATED_BODY()

// 类型别名定义
using FCategoryMap = TMap<FName, TArray<FItemConfig>>;
using FHeaderMap = TMap<FName, TSharedPtr<SHeaderWidget>>;
typedef TMap<int32, FString> FItemNameMap;

private:
// 使用类型别名
FCategoryMap CategoryItems; // 分类项目映射
};
  1. 委托定义:
    • 全局委托定义应放在类外,generated.h文件后空几行添加
    • 类内委托定义应与其UPROPERTY实例一起放置
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      // 全局委托定义
      DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnGameStartEvent);

      UCLASS()
      class EXAMPLE_API UMyClass : public UObject
      {
      GENERATED_BODY()

      public:
      // 类内委托定义和实例
      DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnItemSelectedEvent, int32, ItemID);
      UPROPERTY(BlueprintAssignable, Category = "Events")
      FOnItemSelectedEvent OnItemSelected;
      };

属性声明规则

  1. 非UPROPERTY成员变量:

    • 注释放在变量同一行且位于变量后面
    • 变量可以按功能分组,组之间使用空行隔开
    • 同组内的变量类型、变量名和注释应对齐
      1
      2
      3
      4
      5
      6
      7
      8
      private:
      // 数据相关变量
      FTextBlockStyle CommandTextStyle; // 命令文本样式
      TArray<FCommandConfig> ConfigArray; // 配置数组

      // UI组件相关变量
      TSharedPtr<class SButton> ConfirmButton; // 确认按钮
      TSharedPtr<class STextBlock> ButtonText; // 按钮文本
  2. UPROPERTY成员变量:

    • 注释放在UPROPERTY宏上方
    • 属性应按功能分组
      1
      2
      3
      4
      5
      6
      7
      8
      private:
      // 玩家基础属性
      UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "玩家属性")
      float MaxHealth;

      // 当前生命值
      UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "玩家属性")
      float CurrentHealth;

函数声明规则

  1. UFUNCTION标记函数:

    • 注释放在UFUNCTION宏的上方
    • 所有UFUNCTION宏标记的函数应放在一起
      1
      2
      3
      // 处理按钮点击事件
      UFUNCTION(BlueprintCallable, Category = "UI事件")
      void HandleButtonClicked();
  2. 虚函数重写:

    • 虚函数重写应放在UFUNCTION函数后面
    • 如果函数同时有UFUNCTION标记和override,则归类为UFUNCTION函数
      1
      2
      // 在销毁前释放资源
      virtual void BeginDestroy() override;
  3. 普通函数:

    • 具有相同功能的函数应放在一起,并使用注释分组
    • 注释放在函数声明同一行的后面,并应对齐
      1
      2
      3
      4
      5
      6
      7
      // UI相关函数
      void InitializeComponents(); // 初始化组件
      void UpdateUI(); // 更新UI显示

      // 事件处理函数
      FReply HandleHistoryButtonClicked(); // 处理历史记录按钮点击
      FReply HandleSearchButtonClicked(); // 处理搜索按钮点击

代码格式规则

  1. 大括号:

    1
    2
    3
    if (bIsValid) {
    DoSomething();
    }
  2. 缩进: 使用4个空格

  3. 空行: 函数之间使用一个空行分隔

注释规则

  1. 类注释:

    1
    2
    3
    /**
    * 玩家角色类 - 处理玩家输入和状态
    */
  2. 函数注释:

    • UFUNCTION标记的函数:注释放在UFUNCTION上方

      1
      2
      3
      // 更新角色健康状态并检查是否死亡
      UFUNCTION(BlueprintCallable)
      void UpdateHealth(float DeltaHealth);
    • 普通函数:注释放在函数声明同一行后面,并对齐

      1
      2
      void UpdateUI();                            // 更新UI显示
      FReply HandleButtonClicked(); // 处理按钮点击
  3. 变量分组注释: 使用单行注释标识变量组

    1
    2
    3
    // UI组件引用 - Slate实现部分
    TSharedPtr<class SVerticalBox> MainVerticalBox; // 主垂直布局盒子
    TSharedPtr<class SHorizontalBox> TabButtonsBox; // 标签按钮水平布局盒子
  4. 函数分组注释:使用单行注释标识功能相关的函数组

    1
    2
    3
    // UI构建函数
    void BuildTabButtons(); // 构建标签按钮
    void BuildMainLayout(); // 构建主布局

蓝图交互规则

  1. 类标记:

    1
    UCLASS(Blueprintable, BlueprintType)
  2. 属性标记:

    1
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "属性")
  3. 函数标记:

    1
    UFUNCTION(BlueprintCallable, Category = "功能")

内存管理规则

  1. 使用智能指针:

    1
    TSharedPtr<FMyClass> MyObject;
  2. 正确释放资源:

    1
    virtual void BeginDestroy() override;

性能优化规则

  1. 避免在Tick中执行重型计算
  2. 使用委托代替轮询
  3. 使用异步加载大型资源

网络复制规则

  1. 标记需要复制的属性:

    1
    2
    UPROPERTY(Replicated)
    float Health;
  2. 实现复制函数:

    1
    void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

调试支持规则

  1. 使用适当的日志级别:

    1
    UE_LOG(LogCategory, Log, TEXT("玩家%s加入了游戏"), *PlayerName);
  2. 使用断言确保条件:

    1
    check(Player != nullptr);