P78_ Blaster HUD And Player Controller
P78_1 创建PC和HUD
P78_2 Tick Component => SetHUDCrosshairs()
P79_ Drawing the Crosshairs
- DrawHUD() Call Every Tick.
#include "HUD/BlasterHUD.h"
void ABlasterHUD::DrawHUD()
{
Super::DrawHUD();
FVector2D ViewportSize;
if (GEngine) {
GEngine->GameViewport->GetViewportSize(ViewportSize);
const FVector2D ViewportCenter = FVector2D(ViewportSize.X / 2.0f , ViewportSize.Y / 2.0f);
if (HUDPackage.CrosshairsCenter) {
DrawCrosshair(HUDPackage.CrosshairsCenter,ViewportCenter);
}
if (HUDPackage.CrosshairsLeft) {
DrawCrosshair(HUDPackage.CrosshairsLeft, ViewportCenter);
}
if (HUDPackage.CrosshairsRight) {
DrawCrosshair(HUDPackage.CrosshairsRight, ViewportCenter);
}
if (HUDPackage.CrosshairsTop) {
DrawCrosshair(HUDPackage.CrosshairsTop, ViewportCenter);
}
if (HUDPackage.CrosshairsBottom) {
DrawCrosshair(HUDPackage.CrosshairsBottom, ViewportCenter);
}
}
}
void ABlasterHUD::DrawCrosshair(UTexture2D* Texture, FVector2D ViewportCenter)
{
const float TextureWidth = Texture->GetSizeX();
const float TextureHeight = Texture->GetSizeY();
const FVector2D TextureDrawPoint(
ViewportCenter.X - (TextureWidth / 2.0f),
ViewportCenter.Y - (TextureHeight / 2.0f)
);
DrawTexture(
Texture,
TextureDrawPoint.X,
TextureDrawPoint.Y,
TextureWidth,
TextureHeight,
0.0f,
0.0f,
1.0f,
1.0f,
FLinearColor::White);
}
P80_ Crosshair Spread
- 本节不涉及网络内容.
P81_1 BlasterHUD
P81_1_1 BlasterHUD.h
- 在结构体中加入了印象准信扩散的因素.
- 设置一个变量代表准星可以扩散的最大值.
P81_1_2 BlasterHUD.cpp
- 计算并应用准星扩散.
P81_2 CombatComponent
P81_2_1 CombatComponent.h
- 创建两个变量存储计算的准星Factor.
P81_2_2 CombatComponent.cpp
- 通过地速和bIsInAir 计算准星扩散因子.
P81_Correcting the Weapon Rotation
- 修正武器朝向,让其开火时朝向子弹发射方向.
P81_1 BlasterAnimInstance::Update
- 这里 IsLocallyControlled 的限制 和 BlasterCharacter 中 HitTarget 变量并不是复制的 , 所以这个调整武器旋转的行为只会在本地进行, 并不会同步也不需要同步到其他客户端上.
P81_2 修改 FABRIK逻辑的位置.
- 当我们 Transform hand_r bone 后 , 发现 FABRIK 无效了 , 这个因为 FABRIK 逻辑需要再 Transform bone 逻辑之后运行.
- 这里新建了状态机.
P81_3 只在本地校准武器朝向
- 详见上面两个截图 , 因为其他端对于是否看见武器有偏移并无影响.
P82_ Zoom While Aiming
P82_1 Zoom While Aiming
- Call in TickComponent , 涉及 Camera 的内容只在本地执行就行了.
P82_2 解决一下 Zoom过大 时 模糊的问题
P83_ Shrink Crosshair when Aiming And Fire
P83_1 Shrik Crosshair When Aim
P83_2 Spread Crosshair When Fire
- 开火时设置因子.
- 每帧都在 Interpto 0.0f.
P84_ Change Crosshair Color
- We Can Change out Crosshair Red When We Aiming at Another Player For Example.
P84_1 创建了一个接口用于和准星交互.
P84_2 BlasterCharacter 实现了该接口.
P84_3 CombatComponent 射线检测.
P84_4 在 HUD 中动态修改准星的颜色.
P84_5 修改一下 BlasterCharacter SkelMesh 的碰撞.
- 检查一下.
P84_6 Interp Weapon Rotaion
P85_ Extending the Trace Start
P85_1 目前 LineTrace 存在的一些问题_1
- 我们这个射线检测到了自己.
- 射线检测到了视野上的角色,即使这个角色我们没在瞄准.
- 可以把 Trace Start Point 设置为同一方向上,但是在角色的前面.
P85_2 把 Trace Start Point 设置为同一方向上,但是在角色的前面.
P85_3 目前 LineTrace 存在的一些问题_2
- 靠墙之后什么都看不见.
P85_4 Hide the Character When Camera is Too Close to the Mesh
P86_ Hitting the Character
P86_1 创建 Hit Montage
P86_2 ProjectileOnHit
P86_3 修改并检查Projectile 的 Collision 的碰撞设置
P86_4 安装 Hit React AnimMontage Slot
P86_5 Multicast HitReact Montage
- NetMulticast In BlasterCharacter.
- Projectile Call Multicast RPC Of Character.
- NetMulticast Unreliable.
P86_6 取消胶囊体会对子弹产生影响
P86_6_1 给 角色 Mesh 创建单独的 ObjectType
P86_6_2 设置 Projectile 的 CollisionResponse
P86_6_3 设置角色Mesh
P87_ Smooth Rotation for Proxies
- 利用 OnRep_ReplicatedMovement , 让 TurnInPlace逻辑更加平滑.
- Aim Offset 的时候一直在抖动.
- 发生这种抖动的原因是我们在动画蓝图中进行这个Rotate Root Bone 逻辑 ,动画蓝图的更新频率比正常的Tick频率要小的多.
- 所以动画蓝图的 Rotate Root Bone 节点对于网络复制的 Movement 来说并不是一个好的解决方案 , 所以我们不会旋转根骨骼 for simulate proxies , 我们需要做的是直接旋转角色 , 当我们的角色旋转控制器.
P87_1 在Tick中区分LocallyRole
- if we are simulatedProxy we Rotate Character Directely.
- if we are not simulatedProxy we Rotate Root Bone In AnimBP.
- In Other Words , we're locallly Controlle either on the server or a client.
P87_1_1 AimOffset()
P87_1_2 SimProxiesTurn()
P87_1_3 AnimBP
- 利用创建的变量区分一下.
P87_2 解决在 SimulateProxy端 瞄准偏移 Pitch 失效的问题
P87_2_1 CalculateAP_Pitch()
- 创建方法我们需要复用这段逻辑.
P87_2_2 Call in AimOffset()
P87_2_3 Call in SimProxiesTurn()
P87_3 Turn In Place In SimulateProxy _V1
P87_3_1 测试结果
- 打印字符串测试.
- 存在为0的情况 , 说明我们在 SimulateProxy Net Update 更新的频率 , 比 Client Locally Controlled 的 AotomomousProxy 的更新频率要慢.
P87_3_2 想个办法解决吧
- This is where replicated movement comes in , every time movement is replicated to a character , there is a rep notify that will be called.
- So we can't calling SimuProxiesTurn() every frame , We Only want to Call this when our simulated proxy gets its movement updated , and that's where OnRep replicated movement comes in.
-
So We overwrite it !!!
- 重写.
- So whenever our actos movement changes and is replicated . this rep notify will be called ,So we can use this instead of the tick function when checking the delta for our character's rotation for simulate proxy.
P87_3_3 取消 SimProxiesTurn() 在 Tick 中的调用.
P87_4 Code 不知道起啥标题了
P87_4_1 Tick
void ABlasterCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//ROLE_None UMETA(DisplayName = "None"), == 0
//ROLE_SimulatedProxy UMETA(DisplayName = "Simulated Proxy"), == 1
//ROLE_AutonomousProxy UMETA(DisplayName = "Autonomous Proxy"), == 2
//ROLE_Authority UMETA(DisplayName = "Authority"), == 3
if (GetLocalRole() > ENetRole::ROLE_SimulatedProxy && IsLocallyControlled()) { //Autonomous And Server Locally Control
AimOffset(DeltaTime);
}
else { // Simulated
//the reason we're keeping track of this is because if thistime reaches a certain amount , meaning
//we haven't had our movement relicated lately , i'd like to call OnRep+Movement directly.
//不移动时每0.25秒强制调用 OnRep_ReplicatedMovement();
TimeSinceLastMovemntReplication += DeltaTime;
if (TimeSinceLastMovemntReplication > 0.25f) {
OnRep_ReplicatedMovement();
}
CalculateAO_Pitch();
}
HideCameraIfCharacterClose();
}
P87_4_2 OnRep_ReplicatedMovement
P87_4_3 SimProxiesTurn()
- 取消对 CalculateAO_Pitch(); 的调用.
P87_5 滑动
- 快速旋转奔跑时会滑动.
- That's Because We're Not Setting out turning status back to not turning as soon as we start running.
- 当速度大于零时,让其快速结束 TurnInPlace 行为.
P87_6 总结一下
P88_ Automatic Fire
- 本节不涉及网络内容.