unity2UE(正在更新)
接下来每一章可能抽取一部分观看,后续再进行补充
章节序号 | 章节名 | 进度 | 备注 |
---|---|---|---|
1 | 介绍 | 2/2 | |
2 | 创建多人游戏插件 | 0/23 | 等学习到网络回头写 |
3 | 创建项目 | 10/14 | 只有10节课 |
4 | 武器 | 2/24 |
插件编写(待)
这边我先开盖即用插件
Play设置
编译模式
模式 | 用途描述 | 编译特点 | 文件/性能特点 |
---|---|---|---|
DebugGame | 开发过程中进行调试。在游戏中设置断点、查看变量值以及代码调试。 | 以调试模式编译,包含调试符号(debug symbols)。 | 可执行文件较大且运行速度较慢。 |
Development | 开发过程中进行内部测试和验证。相比DebugGame模式会进行更多优化,同时保留调试能力。 | 启用优化选项以提高运行性能,保留部分调试信息。 | 运行性能更高,但仍便于问题排查。 |
DebugGame Editor | 在Unreal Editor中调试游戏功能(与DebugGame模式类似,但专用于编辑器环境)。 | 编译包含调试符号,便于在编辑器中调试。 | 可执行文件较大,运行效率较低。 |
Development Editor | 在Unreal Editor中进行开发测试。优化编辑器运行性能,同时保留调试能力(与Development模式类似)。 | 启用优化选项提高编辑器性能,保留部分调试信息。 | 编辑器运行更流畅,同时支持问题排查。 |
Shipping | 发布给玩家的正式版本构建。 | 全面优化编译,移除所有调试符号和调试信息。 | 可执行文件最小化,运行性能最高(无调试开销)。 |
网络模式(ENetMode)
更新插件代码
1 | // 原弃用代码:bIsFocusable = true; |
基础3C
项目建立
- 编译项目
- 装入自定义网络插件
- 装入Online SubSystem Steam
- 设置ini:
在DefaultEngine.ini写入
1 | [/Script/Engine.GameEngine] |
在DefaultGame.ini写入
1 | [/Script/Engine.GameSession] |
删除二进制文件夹
创建关卡
- 创建StartUpMap,LobbyMap
- 在Project Setting - Map&Modes - 里面更换默认的Map
- 在StartUpMap关卡蓝图里面调用Create WBP Menu widget -> Menu Setup (设置Lobby路径)
Bulid
- 设置bulid的map : 在Project Setting - 搜索 maps to 设置俩个关卡
- 平台-打包-windows-放入新建的build文件夹
建立网络连接
- 在内容浏览器里面ADD 第三人称资产
- 重点概念 input (待定)
- GameMode设置第三人称 -
资源
重定向(待定)重定向教程
3C
Character
新建一个cpp类 注意
1 | #include "FCharacter.h" |
头文件path要对,新建立的时候默认h会错误
每次更新都 ====在编辑器或游戏窗口中按下 **Ctrl + Alt + F11
**,强制终止当前 Live Coding 进程,释放资源后重新编译
C++类创建蓝图 并且设置Mesh和pos
Camera
FCharacter
1 |
|
Control
project setting - Engine Input (类似unity Input Manager)
设置人物BP_FCharacter - Pawn - 自动控制玩家 - 选择玩家0
FCharacter
1 | // Called to bind functionality to input |
Anim
FAnimInstance
1 | void UFAnimInstance::NativeInitializeAnimation() |
动画蓝图创建
- 类设置 - 父类设置为 F Anim Instance
创建状态机
- 创建状态
- 创建连线
- 创建连线条件
创建混合空间(混合空间1D和混合空间的区别)混合空间
- 放入 Idle Walk Run 三个动画
- X轴设置为Speed
- 放入动画状态机 中 并且输入设置为CPP文件中的Speed
修改动画手感与摄像机小优化
自由摄像机视角
- FCharacter.cpp
1 | //动画后的优化 |
- BP_FCharacter - 使用控制器旋转Yaw - false
- CharMoveComp - 将旋转朝向运动 - true
下落bug
- 下落动画Loop
无缝切换
(99+ 封私信 / 80 条消息) 关卡系统四、无缝切换 - 知乎
对于地图切换(也即关卡切换),UE还提供了无缝切换(Seamless Travel)和非无缝切换(Non-Seamless Travel),无缝切换使用异步加载关卡资源,是非阻塞式切换,而非无缝切换即为前面介绍的同步加载关卡资源,是阻塞式切换(传送门),在网络联机游戏中,无缝切换不会导致网络断开,而非无缝会导致网络断开后重连,UE推荐在网络联机游戏中使用无缝切换,感兴趣可以看看官方文档(有点晦涩难懂T_T,因此需要深入研究一番)。
GameMode
创建FLobbyGameMode
设置Pawn为FCharacter
创建过度关卡
在Project Setting 里面设置过度关卡
在GameMode中设置无缝切换
1 | void AFLobbyGameMode::PostLogin(APlayerController* NewPlayer) |
HUD
- 创建HUD Class
- 创建WBP继承与HUD Class
- 在代码中绑定WBP
- 在FCharacter中设置WBP类以及展示Canvas
- 在FCharacter蓝图中反射调用UpdateText
1 | void UFPlayerHUDWidget::SetDisplayText(const FString& TextToDisplay) |
GetRemoteRole
主要API
11.Camera
CreateDefaultSubobject
是 Unreal Engine(UE)中用于创建组件或子对象的核心函数,主要在 C++ 中实现 Actor 或组件的初始化。
1 | T* CreateDefaultSubobject<TReturnType>(FName SubobjectName, bool bIsRequired = true, bool bIsTransient = false); |
- **
TReturnType
**:需创建的组件类型(如USpringArmComponent
)。 SubobjectName
:组件唯一标识(同一 Actor 内不可重复)- **
bIsTransient
**:若为true
,组件不会被序列化(适用于临时对象)
SetupAttachment
是用于建立组件层级关系的核心方法,主要作用是将一个组件(子组件)附加到另一个组件(父组件)上,形成父子依赖关系。
1 | void USceneComponent::SetupAttachment(USceneComponent* Parent, FName SocketName = NAME_None); |
反射 - UPROPERTY
Weapon
这边开始以阅读源码方式去处理代码部分,可能涉及到下面课程的部分,但主要还是看引擎操作流程。
1-Weapon Class
创建CPP FWeaponBase
编写代码
- 代码内容为AFWeaponBase 的创建组件与网格碰撞(详见主要API 碰撞)的设置
- 创建组件如下的1.2,1.5-1.10
- 网格碰撞如下的3.1-3.4
创建BP
- BP继承与FWeaponBase
- 设置Mesh
碰撞
UE4 物理碰撞(C++)_setcollisionresponsetochannel-CSDN博客
SetCollisionResponseToAllChannels(ECollisionResponse Response) |
设置组件对所有通道的统一响应 | Response : Ignore 、Overlap 或 Block |
快速全局设置(如禁用所有碰撞) |
---|---|---|---|
SetCollisionResponseToChannel(ECollisionChannel Channel, ECollisionResponse Response) |
设置组件对单个通道的响应 | Channel : 目标通道(如ECC_WorldStatic ) Response : 响应类型 |
精细化控制(如角色忽略子弹通道) |
SetCollisionEnabled(ECollisionEnabled::Type Type) |
启用/禁用碰撞检测 | Type : NoCollision 、QueryOnly (仅检测)、PhysicsOnly (仅物理)、QueryAndPhysics |
动态开关碰撞检测(如死亡后禁用) |
通道名称 | 枚举值 | 主要用途 | 典型应用场景 |
---|---|---|---|
WorldStatic | ECC_WorldStatic |
静态环境物体(不可移动) | 墙壁、地面、建筑物等场景静态元素的碰撞阻挡 。 |
WorldDynamic | ECC_WorldDynamic |
动态物体(可移动或受物理影响) | 可移动平台、可破坏物、开关门等动态交互对象 。 |
Pawn | ECC_Pawn |
玩家或AI控制的角色 | 角色移动碰撞、AI视线检测、玩家与NPC的交互 。 |
PhysicsBody | ECC_PhysicsBody |
受物理模拟影响的物体 | 滚石、箱子、布娃娃等物理驱动对象的碰撞检测 。 |
Visibility | ECC_Visibility |
可见性检测(非物理阻挡) | 光线追踪、玩家视线判断、渲染剔除优化 。 |
Camera | ECC_Camera |
摄像机碰撞检测 | 防止摄像机穿墙、第三人称视角的镜头避障 。 |
Destructible | ECC_Destructible |
可破坏物体 | 栅栏、玻璃、爆炸物等可破坏对象的碰撞响应 。 |
Vehicle | ECC_Vehicle |
载具类对象 | 汽车、坦克、飞行器等载具的物理碰撞与交互 。 |
Gameplay | ECC_GameTraceChannelN |
预留的自定义游戏逻辑通道(N=1~8 ) |
武器检测(Weapon )、拾取物(Pickup )、陷阱触发等专属交互 。 |
2-Pickup Widget
创建WBP Pickup
加入Text
编写代码 - 添加子物体
- 创建WBP引用
BP_Weapon中
- 设置Pickup Widget
- Space-Screen
- Widget Class - WBP Pickup
- 所需大小绘制-true
- 设置Pickup Widget
编写代码
OnSphereOverlap 当有物体进入拾取区域时调用
必须是U函数
1
void AFWeaponBase::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
- 绑定事件委托
1 | AreaSphere->OnComponentBeginOverlap.AddDynamic(this, &AFWeaponBase::OnSphereOverlap); // 3.5 绑定重叠开始事件 |
委托
[UE4]委托代理:单播委托,多播委托,动态单播委托,动态多播委托,事件_ue 多播委托-CSDN博客
特性 | 单播委托 | 多播委托 | 动态单播委托 | 动态多播委托 |
---|---|---|---|---|
绑定数量 | 仅绑定 1个 函数 | 可绑定 多个 函数 | 仅绑定 1个 函数 | 可绑定 多个 函数 |
执行方式 | .Execute() |
.Broadcast() |
.Execute() |
.Broadcast() |
蓝图支持 | ❌ 不支持蓝图绑定 | ❌ 不支持蓝图绑定 | ✅ 支持蓝图绑定(需UFUNCTION ) |
✅ 支持蓝图绑定(需UFUNCTION ) |
线程安全 | 非线程安全 | 非线程安全 | 非线程安全 | 非线程安全 |
声明宏 | DECLARE_DELEGATE[_Xxx] |
DECLARE_MULTICAST_DELEGATE[_Xxx] |
DECLARE_DYNAMIC_DELEGATE[_Xxx] |
DECLARE_DYNAMIC_MULTICAST_DELEGATE[_Xxx] |
典型用例 | 一对一回调(如任务完成通知) | 事件广播(如伤害事件通知多个系统) | 蓝图与C++交互的单次回调 | 蓝图可订阅的事件系统(如UI事件) |
3- Variable Replication
复制变量设置
- 在Character设置新变量为复制变量(详见主要API 复制变量)
- 重写 virtual void GetLifetimeReplicatedProps(TArray
& OutLifetimeProps) const override; - 这边TArray(详见主要API 数据容器)
- DOREPLIFETIME
内联宏 FORCEINLINE(详见主要API 内联宏)
DOREPLIFETIME_CONDITION(AFCharacter,OverlappingWeapon,COND_OwnerOnly)
复制时回调函数
1 | UPROPERTY(ReplicatedUsing = OnRep_OverlappingWeapon) |
- SetOverlappingWeapon
1 | void AFCharacter::SetOverlappingWeapon(AFWeaponBase* Weapon) |
这边使用了IsLocallyControlled()
退出碰撞函数
1 | UFUNCTION() |
设置Rep回调函数多一个变量
1
2UFUNCTION()
void OnRep_OverlappingWeapon(AFWeaponBase* lastWeapon);注:这边lastWeapon 会有值(代表着被销毁的前一帧),但是OverlappingWeapon 可能为空,
网络复制
在虚幻引擎(Unreal Engine)中,UPROPERTY(Replicated)
是一个核心宏,用于声明一个网络复制的属性。其作用是标记该变量(属性)的值需要从服务器(Server)自动同步到所有相关的客户端(Client),以实现多人游戏中状态的一致性。
1. 声明复制属性
1 | UPROPERTY(Replicated) |
2. 重写 GetLifetimeReplicatedProps
函数
在属性所属的类中重写此函数,注册需复制的变量:
1 | #include "Net/UnrealNetwork.h" // 必须包含此头文件 |
DOREPLIFETIME
宏是复制注册的关键。
3. 启用Actor复制
在Actor的构造函数中设置:
1 | AMyActor::AMyActor() { |
该宏确保 OverlappingWeapon
(角色当前重叠的武器对象)仅在特定条件下从服务器同步到客户端。通过 COND_OwnerOnly
条件,仅同步给控制该角色的客户端,其他客户端(如队友或敌人)不会收到此数据
**ReplicatedUsing
**:指定同步后的回调函数为 OnRep_OverlappingWeapon
,即属性值在客户端更新后自动触发此函数
数据容器(代替STL)
UE C++基础 | 常用数据容器 | TArray、TMap、TSet_emplace tmap-CSDN博客
DOREPLIFETIME宏
在虚幻引擎(Unreal Engine)中,DOREPLIFETIME(AFCharacter, OverlappingWeapon)
是一个核心宏,用于注册需要网络同步的属性,确保服务器上 AFCharacter
类中 OverlappingWeapon
变量的值能自动同步到所有客户端。以下是详细解析:
🔧 一、功能与作用
- 网络同步机制
- 当服务器修改
OverlappingWeapon
(如角色拾取武器)时,该宏会触发引擎自动将新值广播给所有客户端。 - 客户端收到数据后更新本地副本,无需手动处理同步逻辑,确保多人游戏中状态一致。
- 当服务器修改
- 使用场景
- 适用于需跨客户端同步的
Actor
引用(如角色当前重叠的武器对象)。 - 典型案例:角色靠近武器时,客户端需实时显示武器可拾取提示。
- 适用于需跨客户端同步的
⚙️ 二、底层实现原理
依赖函数
该宏需在AFCharacter
类的GetLifetimeReplicatedProps
函数中调用:1
2
3
4void AFCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AFCharacter, OverlappingWeapon); // 注册同步属性
}- 头文件要求:必须包含
#include "Net/UnrealNetwork.h"
。
- 头文件要求:必须包含
属性声明
OverlappingWeapon
需用UPROPERTY(Replicated)
标记为可复制属性:1
2UPROPERTY(Replicated)
class AWeapon* OverlappingWeapon; // 声明为可复制引用Actor复制启用
在AFCharacter
构造函数中需设置:1
2
3AFCharacter::AFCharacter() {
SetReplicates(true); // 启用Actor的网络复制能力
}
📊 三、同步流程与数据流
步骤 | 服务器 | 客户端 |
---|---|---|
属性修改 | 调用 SetOverlappingWeapon(NewWeapon) |
- |
检测变化 | 引擎自动检测 OverlappingWeapon 变更 |
- |
广播更新 | 发送新值给所有客户端 | 接收更新数据 |
应用更新 | - | 自动更新本地 OverlappingWeapon 值 |
⚠️ 注意:客户端不能直接修改
Replicated
属性,否则会与服务器值冲突。
🛠️ 四、高级用法
条件复制
通过DOREPLIFETIME_CONDITION
限制同步范围,优化带宽:1
DOREPLIFETIME_CONDITION(AFCharacter, OverlappingWeapon, COND_OwnerOnly);
条件类型 作用 COND_InitialOnly
仅首次同步时复制(如初始装备) COND_OwnerOnly
仅同步给控制该角色的客户端 复制通知(RepNotify)
使用ReplicatedUsing
在属性同步后触发客户端逻辑:1
2
3
4
5
6
7UPROPERTY(ReplicatedUsing = OnRep_OverlappingWeapon)
AWeapon* OverlappingWeapon;
UFUNCTION()
void OnRep_OverlappingWeapon() {
if (OverlappingWeapon) ShowPickupWidget(true); // 显示拾取UI
}- 客户端属性更新后自动调用
OnRep_OverlappingWeapon
。
- 客户端属性更新后自动调用
⚠️ 五、常见问题与注意事项
权限验证
修改复制属性的代码需在服务器执行:1
2
3
4
5void AFCharacter::SetNewWeapon(AWeapon* Weapon) {
if (HasAuthority()) { // 仅服务器可修改
OverlappingWeapon = Weapon;
}
}适用对象限制
- 仅继承自
AActor
的类支持属性复制(如AFCharacter
)。 - 非
Actor
类(如UObject
)需通过 RPC 或序列化同步。
- 仅继承自
性能优化
- 避免高频同步属性(如每帧更新的位置),优先使用内置组件(如
CharacterMovementComponent
)。 - 对低频属性(如装备状态、交互对象)使用复制更高效。
- 避免高频同步属性(如每帧更新的位置),优先使用内置组件(如
💎 总结
DOREPLIFETIME(AFCharacter, OverlappingWeapon)
是虚幻引擎网络同步的核心机制,通过声明-注册模式实现属性自动同步。结合 ReplicatedUsing
可扩展客户端响应逻辑,而条件复制能进一步优化带宽。在多人游戏中,合理使用该宏可显著提升状态同步的效率和可靠性。
IsLocallyControlled
在Unreal Engine的多人游戏开发中,类似 IsLocallyControlled()
的函数主要用于处理网络角色控制权、执行权限和同步逻辑的判断。以下是关键函数及其作用分类说明,结合了Unreal Engine的网络同步机制设计:
🔧 一、角色控制权与执行端判断
IsLocallyControlled()
- 功能:判断当前角色是否由本地玩家控制(客户端视角)。
- 典型场景:客户端特效播放、本地UI更新(如武器拾取提示)。
HasAuthority()
- 功能:判断当前逻辑是否在服务端(Authority)执行。
- 场景:关键状态修改(如生命值扣除)、生成网络同步对象(如武器掉落),确保仅服务端修改全局状态。
IsNetMode(ENetMode Mode)
功能:检测当前网络模式(如客户端、服务端、独立运行)。
常用模式
:
NM_Client
:当前为客户端。NM_DedicatedServer
:专用服务器。NM_ListenServer
:监听服务器(同时是主机客户端)。
📡 二、网络执行函数变体
GetWorld()->IsServer()
/GetWorld()->IsClient()
- 功能:直接判断当前运行环境是服务端或客户端,与
HasAuthority()
类似但更直观。
- 功能:直接判断当前运行环境是服务端或客户端,与
RunOnServer
(RPC函数限定符)- 功能:通过标记
UFUNCTION(Server, Reliable)
,强制函数逻辑在服务端执行。 - 场景:客户端发起攻击请求时,需服务端验证并广播同步。
- 功能:通过标记
Client
/NetMulticast
RPC功能
:从服务端向客户端广播事件:
Client
:仅发送给控制该角色的客户端。NetMulticast
:发送给所有客户端。
场景:播放全局特效(如爆炸)、更新多人UI。
⚙️ 三、属性同步与响应函数
OnRep_[PropertyName]()
- 功能:属性标记为
Replicated
后,当属性在客户端同步时自动触发的回调函数。 - 场景:客户端根据同步后的生命值更新血条UI。
- 功能:属性标记为
GetNetMode()
- 功能:返回当前网络模式枚举值(比
IsNetMode
更灵活),用于分支逻辑处理。
- 功能:返回当前网络模式枚举值(比
📊 关键函数对比表
函数/方法 | 判断目标 | 典型应用场景 |
---|---|---|
IsLocallyControlled() |
角色是否本地控制 | 本地UI显示、输入响应 |
HasAuthority() |
是否在服务端执行 | 关键状态修改、生成同步对象 |
IsNetMode(NM_Client) |
当前是否为客户端环境 | 环境适配逻辑(如禁用客户端物理) |
OnRep_Health() |
客户端属性同步完成 | 更新本地UI或播放特效 |
UFUNCTION(Server) |
强制函数在服务端运行 | 客户端发起的动作请求(如拾取武器) |
UFUNCTION(NetMulticast) |
服务端向所有客户端广播 | 全局事件(如游戏开始通知) |
💡 四、组合使用示例
1 | void AMyCharacter::TryPickupWeapon(AWeapon* Weapon) { |
此代码体现了以下设计原则:
- 本地控制判断(
IsLocallyControlled
)触发客户端请求 → - 服务端权限验证(
HasAuthority
)执行逻辑 → - 广播事件(
NetMulticast
)同步到所有客户端。
⚠️ 注意事项
- 避免在客户端修改同步属性:所有需网络同步的属性修改必须通过服务端执行,否则会被引擎覆盖。
- RPC的可靠性选择:关键事件(如角色死亡)用
Reliable RPC
;高频非关键事件(如位置微调)用Unreliable RPC
。 - 网络优化:通过
NetUpdateFrequency
控制属性同步频率,平衡带宽与实时性需求。
这些函数共同构成了Unreal Engine多人游戏开发的底层框架,理解其差异和适用场景是保证网络同步一致性与性能的关键。