LinearGradient 梯度节点
LinearGradient 梯度节点
MakeMaterialAttributes
定义多个材质属性
BlendMaterialAttributes
材质混合
Panner 平移节点
BumpOffset 高度偏移
Depth Fade 深度渐隐
接触其他物体渐隐
Fresnel 菲涅尔 外发光
TGProject.Build 里添加 插件
public TGProject(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay",
"EnhancedInput", "OnlineSubsystem", "OnlineSubsystemUtils" });
}
VS 属性页 调试 添加 命令参数
void ATGProjectCharacter::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
UE_LOG(MYLog____ATGProjectCharacter, Log, TEXT("---PossessedBy---32323232323"));
if (GetNetMode() == NM_DedicatedServer)
{
if (UTGProjectGameInstance* GI = GetGameInstance<UTGProjectGameInstance>())
{
if (ATGProjectPlayerState* PS = GetPlayerState<ATGProjectPlayerState>())
{
//读存档
bool IsNeedDataTable = true;
if (UTGSettings::Get().bSaveGame)
{
UTGSaveGame* SaveGame = Cast<UTGSaveGame>(UGameplayStatics::LoadGameFromSlot(FString("TGSaveGame_" + PS->GetPlayerName()), 0));
if (SaveGame)
{
PS->SetPlayerCurHP(SaveGame->SG_CurHP);
PS->SetPlayerMaxHP(SaveGame->SG_MaxHP);
IsNeedDataTable = false;
}
}
//读表
if (IsNeedDataTable)
{
if (GI->PlayerInitData)
{
FTGPlayerInitData* PlayerData = GI->PlayerInitData->FindRow<FTGPlayerInitData>(PlayerInitRowName, TEXT(""));
if (ensure(PS))
{
PS->SetPlayerCurHP(PlayerData->MaxHP);
PS->SetPlayerMaxHP(PlayerData->MaxHP);
}
}
}
}
}
}
}
void ATGProjectPlayerState::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (UTGSettings::Get().bSaveGame)
{
if (GetNetMode() == NM_DedicatedServer)
{
//创建游戏保存
UTGSaveGame* SaveGame = Cast<UTGSaveGame>(UGameplayStatics::CreateSaveGameObject(UTGSaveGame::StaticClass()));
if (SaveGame)
{
SaveGame->SG_CurHP = CurHP;
SaveGame->SG_MaxHP = MaxHP;
//保存文件
UGameplayStatics::SaveGameToSlot(SaveGame, FString("TGSaveGame_" + GetPlayerName()), 0);
}
}
}
Super::EndPlay(EndPlayReason);
}
FURL map;
map.Op.add()
向服务器传递消息
GameMode
Login 接收登录事件
FString PN = UGameplayStatics::ParseOption(Options, FString("PN"));
FCommandLine::Get() 获取当前游戏的命令行参数字符串
DEFINE_LOG_CATEGORY_STATIC(MYLog____ATGProjectGameInstance, Log, All)
添加打印宏
UE_LOG(MYLog____ATGProjectGameInstance,
if (FParse::Value(FCommandLine::Get(), TEXT("PlayerName="), PlayerName))
{
UE_LOG(MYLog____ATGProjectGameInstance, Log, TEXT("----Init----PlayerName = %s"), *PlayerName);
}
UPROPERTY() 不会被回收
ensure
宏ensure
是 Unreal Engine 提供的一个调试宏,它用于 验证一个条件是否为真,如果条件为假,则会:
ensure(Condition);
PossessedBy() 指定完控制器后
就可以读取数据了
服务端 或者 单机状态下 才调用
客户端除外
基本数据-》结构-》表格
USTRUCT(BlueprintType)
定义可用于蓝图的结构体
UPROPERTY(EditAnywhere,BlueprintReadWrite)
定义蓝图可访问的变量
TEnumAsByte<ECharacterColorType::ColorType>
是什么意思?在 Unreal Engine C++ 代码中,TEnumAsByte<T>
是一个模板类,它的作用是将 枚举(enum) 存储为 一个字节(uint8
),而不是默认的 4 字节 int32
。这样可以节省内存,特别是在结构体或 UPROPERTY
变量中。
DECLARE_DELEGATE_OneParam(FOnPlayerCurHPChange, float);
单播委托,即 只能绑定一个函数。
DECLARE_DYNAMIC_DELEGATE_OneParam
动态单播
DECLARE_MULTICAST_DELEGATE_OneParam(FOnPlayerMaxHPChange, float);
多播委托,可以 绑定多个函数。
DECLARE_DYNAMIC_MULTICAST_DELEGATE
动态多播
OnPlayerCurHPChange.ExecuteIfBound(GetPlayerCurHP());
执行单播
OnPlayerMaxHPChange.Broadcast(GetPlayerMaxHP());
执行多播
OnPlayerCurHPChange
是一个 DECLARE_DELEGATE_OneParam
定义的委托。
ExecuteIfBound()
检查委托是否绑定,如果绑定了,就执行。
GetPlayerCurHP()
是一个返回 float
的函数,获取玩家当前血量。
PS->OnPlayerCurHPChange.BindUObject(this, &UUI_PlayerInfoUI::SetPlayerCurHP);
绑定单播
PS->OnPlayerMaxHPChange.AddUObject(this, &UUI_PlayerInfoUI::SetPlayerMaxHP);
绑定多播
UFUNCTION(Reliable, Clien)
服务器调用,仅自己客户端执RunOnOwningClient>
UFUNCTION(Reliable, Server)
客户端调用,服务器执行<血量控制>
UFUNCTION(Reliable, NetMulticast)
服务器调用,服务器和所有客户端执行
同步服务器和客户端事件
宏标记
Reliable 重要 TCP
unreliable 不重要 UDP
UPROPERTY(Replicated)
UPROPERTY(ReplicatedUsing="OnRep_ChangeCurHP")
Replicated
类似,但带有回调函数。OnRep_ChangeCurHP
。
AActor
的变量不会自动同步,必须手动设置 Replicated
。SetReplicates(true)
或 bReplicates = true;
,否则变量不会同步。UPROPERTY(Replicated)
或 UPROPERTY(ReplicatedUsing=OnRep_Function)
。GetWorld() 代表当前关卡的游戏世界。
SpawnActor<AActor> 是 UE5 中用于在世界中创建新 Actor
的方法 T
是模板参数
TSubclassOf<AActor>
是 Unreal Engine 中 表示 AActor
及其子类的泛型类型,用于存储 UClass
类型,但只能是 AActor
或其派生类。
Actor 同步 打开Replicates
UE 提供了 无缝旅行(Seamless Travel),可以让 PlayerState
在切换关卡时保持不变。步骤如下:
游戏实例类
GameInstance
SUper::Init() 父类初始化
Init()
//修改新建 蓝图 打开是独立窗口
编辑器设置-》外观-》资产编辑器打开路径
修改成Main windows
1. 蓝图相关参数
参数 |
作用 |
适用场景 |
BlueprintCallable |
允许蓝图调用该函数 |
蓝图按钮、角色逻辑 |
BlueprintPure |
纯函数,无需执行引脚,不修改对象状态 |
数学运算、数据查询 |
BlueprintImplementableEvent |
蓝图必须实现,C++ 不能定义 |
特效、UI 事件 |
BlueprintNativeEvent |
蓝图可选实现,C++ 可提供默认定义 |
可扩展功能,如 AI 逻辑 |
BlueprintAuthorityOnly |
仅在 服务器 可调用 |
服务器专属逻辑,如物品掉落 |
BlueprintCosmetic |
仅客户端 可执行 |
UI、动画、粒子特效 |
// 示例:蓝图可调用函数
UFUNCTION(BlueprintCallable, Category="Gameplay")
void Jump();
//蓝图里可以调用 Jump(),但 C++ 里仍然可以正常使用。
2. 网络(RPC)相关参数
参数 |
作用 |
适用场景 |
Server |
仅在 服务器 执行(需要 HasAuthority()) |
服务器逻辑(如伤害计算) |
Client |
仅在 客户端 执行(服务器调用) |
客户端特效(如 UI 更新) |
NetMulticast |
服务器执行,并让所有客户端同步执行 |
全体可见效果(如爆炸特效) |
Reliable |
确保 RPC 可靠 传输(数据重要时使用) |
物品拾取、开门 |
Unreliable |
允许 RPC 不可靠 传输(节省带宽) |
瞬时数据,如子弹轨迹 |
// 示例:服务器 RPC
UFUNCTION(Server, Reliable)
void Server_TakeDamage(int32 Damage);
// 客户端调用 Server_TakeDamage(),但代码只会在服务器端执行。
3. 执行权限
参数 |
作用 |
适用场景 |
Exec |
允许在 控制台 输入命令执行 |
调试命令、AI 刷新 |
CallInEditor |
允许在 编辑器模式 执行 |
自动化工具、地图生成 |
//示例:控制台命令
UFUNCTION(Exec)
void SpawnEnemy();
// 在游戏控制台(~ 键)输入 SpawnEnemy 即可执行此函数。
4. 反射系统(反序列化、垃圾回收等)
参数 |
作用 |
适用场景 |
Category="..." |
设定蓝图中的分类 |
组织蓝图函数 |
CustomThunk |
自定义 thunk 代码(高级用法) |
底层优化 |
Meta=(Key=Value) |
额外元数据(用于 UE 反射系统) |
高级蓝图控制 |
//示例:设置蓝图分类
UFUNCTION(BlueprintCallable, Category="Player Actions")
void Sprint();
// 蓝图中 Sprint() 会归类到 "Player Actions" 里。
5. 编辑器功能
参数 |
作用 |
适用场景 |
DeprecatedFunction |
标记函数为 废弃,不推荐使用 |
API 变更 |
SealedEvent |
防止蓝图重写该事件 |
不希望子类修改 |
WithValidation |
RPC 调用前检查参数合法性 |
安全性检查 |
//示例:废弃函数
UFUNCTION(BlueprintCallable, DeprecatedFunction, Category="Legacy")
void OldFunction();
// 蓝图会提示 OldFunction() 已废弃,但仍然可以调用。
6.组合使用示例
UFUNCTION(BlueprintCallable, Server, Reliable, Category="Networking")
void Server_DealDamage(int32 Damage);
UFUNCTION(BlueprintImplementableEvent, BlueprintCosmetic, Category="UI")
void ShowDamageEffect();
//服务器端计算伤害 (Server_DealDamage),客户端显示受伤特效 (ShowDamageEffect)。
PlayerController
。GameMode
还不会创建 Pawn
,只是保证 玩家控制器 已建立。GameMode
允许)。在 GameMode
的 PostLogin
之后,一般还会触发 OnPostLogin
事件,开发者可以在这里进行额外的玩家初始化,比如 匹配系统、分配队伍、同步游戏状态 等。