今天实现一个类似于守望先锋中法鸡的喷气空中悬停功能,具体地实现方法基本上延续了我上一篇冲刺和闪避的方法,就是在我们自定义移动组件MyMovementComponent中添加喷气背包的功能。
具体步骤:
添加以下变量
- bRequestJet 是否喷气的标记位
- MaxFuel 最大燃料量
- FuelCostSpeed 燃料消耗速度
- FuelRecoverSpeed 燃料恢复速度
以上这三个值在构造函数中初始化,可以在UE4编辑器中调整数值
- FuelLeft代表背包中的剩余燃料,一开始在构造函数中初始化成与MaxFuel 一样的数值
这是我尝试后的数值设置
MaxFuel = 800.f;
FuelCostSpeed = 300.f;
FuelRecoverSpeed = 150.f;
FuelLeft = 800.f;
然后是两个代表喷气和不喷气的两个状态改变函数,用于改变标记
uint8 bRequestJet : 1;
UPROPERTY(EditAnywhere, Category = "fuel")
float MaxFuel;
UPROPERTY(EditAnywhere, Category = "fuel")
float FuelCostSpeed;
UPROPERTY(EditAnywhere, Category = "fuel")
float FuelRecoverSpeed;
float FuelLeft;
UFUNCTION(BlueprintCallable, Category = "jet")
void SetJet();
UFUNCTION(BlueprintCallable, Category = "jet")
void SetReleaseJet();
之前的冲刺和闪避都是使用了自定义的移动模式标记位,这次我们不适用自定义的标记位,而使用UE4默认提供的Falling移动模式。我们实现喷气功能的原理就是利用NewFallVelocity函数来计算在喷气动力和重力的共同作用下的新坠落速度,并赋值给Velocity变量。
在OnMovementUpdated中添加以下代码
if (bRequestJet) {
UE_LOG(LogTemp, Warning, TEXT("JetFuelLeft:%f"),FuelLeft);
//bRequestJet = false;
if (FuelLeft > DeltaTime * FuelCostSpeed) {
FuelLeft -= DeltaTime * FuelCostSpeed;
FVector MyNewFallingVelocity = 80 * FVector(0,0,1)* DeltaTime * FuelCostSpeed;
Velocity.Z = NewFallVelocity(MyNewFallingVelocity, FVector(0.f, 0.f, GetGravityZ()), DeltaTime).Z;
}
else if (FuelLeft > 0)
{
FuelLeft = 0.f;
FVector MyNewFallingVelocity = 80 * FVector(0, 0, 1) * DeltaTime * FuelCostSpeed;
Velocity.Z = NewFallVelocity(MyNewFallingVelocity, FVector(0.f, 0.f, GetGravityZ()), DeltaTime).Z;
}
else {
bRequestJet = false;
}
}else {
if (IsMovingOnGround()) {
SetMovementMode(MOVE_Walking);
Velocity.Z = 0.f;
}
else {
Velocity.Z = NewFallVelocity(FVector(0, 0, -500), FVector(0.f, 0.f, GetGravityZ()), DeltaTime).Z;
}
if (FuelLeft != MaxFuel) {
FuelLeft += DeltaTime * FuelRecoverSpeed;
if (FuelLeft > MaxFuel) {
FuelLeft = MaxFuel;
}
}
}
主要功能实现就是如果喷气,就根据FuelCostSpeed减少FuelLeft的值,减少至0后就修改喷气标记为false,如果不喷气了,就根据FuelRecoverSpeed恢复FuelLeft的值,一直到最大值为止。
bRequestJet标记的变动在SetJet和SetReleaseJet中设置。这两个函数后面在蓝图中调用
void UMyCharacterMovementComponent::SetJet() {
if (PawnOwner->IsLocallyControlled())
{
Server_SetJet();
}
bRequestJet = true;
}
void UMyCharacterMovementComponent::SetReleaseJet() {
if (PawnOwner->IsLocallyControlled())
{
Server_SetReleaseJet();
}
bRequestJet = false;
}
其他服务器的一些函数同上篇,这里不再赘述。
最后就是同样的在蓝图中设计我们的逻辑,长按F键时bRequestJet 一直为true,除非燃料耗尽。
松开F键停止喷气,开始恢复燃料。
我们可以在编辑器中按~键,输入showlog回车查看log,代码中写了打印Fuel剩余量的代码
总结
利用UE4本身自带的Falling移动模式实现喷气背包功能,利用NewFallVelocity修改速度