Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2b1e4ba

Browse files
committedSep 14, 2022
port over movement fixes and update info
1 parent fff7c1b commit 2b1e4ba

File tree

6 files changed

+671
-246
lines changed

6 files changed

+671
-246
lines changed
 

‎PBCharacterMovement.uplugin

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"Version": 10,
44
"VersionName": "1.0",
55
"FriendlyName": "Project Borealis Character Movement",
6-
"Description": "Half-Life 2 style character movement in Unreal Engine 4.",
6+
"Description": "Half-Life 2 style character movement in Unreal Engine.",
77
"Category": "Other",
88
"CreatedBy": "Project Borealis",
99
"CreatedByURL": "https://www.projectborealis.com",

‎README.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# PBCharacterMovement
2+
23
Project Borealis character movement component.
34

45
Includes all your standard classic FPS movement from HL2:
@@ -12,14 +13,17 @@ Includes all your standard classic FPS movement from HL2:
1213
* Ramp sliding/trimping/collision boosting
1314
* Smooth crouching and uncrouching, and crouch jumping
1415
* Optional pogo jumping (automatic bunnyhopping)
15-
* WIP Surfing
16+
* Surfing
1617

1718
More info in this blog post: https://www.projectborealis.com/movement.
1819

1920
## Binaries
2021

21-
Binaries are compiled for `4.25`, and will work on Blueprint and C++ projects.
22-
If you are using a different version of Unreal Engine 4, you will need to recompile the plugin.
22+
Binaries are compiled for `4.25`, and will work on C++ projects.
23+
24+
If you have a Blueprint project, you must upgrade to a C++ project, or else the game will fail to package.
25+
26+
If you are using a different version of Unreal Engine, you will need to recompile the plugin.
2327

2428
## Redistribution note
2529

‎Source/PBCharacterMovement/Private/Character/PBPlayerCharacter.cpp

+85-27
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ APBPlayerCharacter::APBPlayerCharacter(const FObjectInitializer& ObjectInitializ
4141

4242
// get pointer to movement component
4343
MovementPtr = Cast<UPBPlayerMovement>(ACharacter::GetMovementComponent());
44+
45+
CapDamageMomentumZ = 476.25f;
4446
}
4547

4648
void APBPlayerCharacter::BeginPlay()
@@ -51,16 +53,75 @@ void APBPlayerCharacter::BeginPlay()
5153
MaxJumpTime = -4.0f * GetCharacterMovement()->JumpZVelocity / (3.0f * GetCharacterMovement()->GetGravityZ());
5254
}
5355

56+
void APBPlayerCharacter::Tick(float DeltaTime)
57+
{
58+
Super::Tick(DeltaTime);
59+
60+
61+
if (bDeferJumpStop)
62+
{
63+
bDeferJumpStop = false;
64+
Super::StopJumping();
65+
}
66+
}
67+
68+
void APBCharacter::ApplyDamageMomentum(float DamageTaken, FDamageEvent const& DamageEvent, APawn* PawnInstigator, AActor* DamageCauser)
69+
{
70+
UDamageType const* const DmgTypeCDO = DamageEvent.DamageTypeClass->GetDefaultObject<UDamageType>();
71+
if (GetCharacterMovement())
72+
{
73+
FVector ImpulseDir;
74+
75+
if (IsValid(DamageCauser))
76+
{
77+
ImpulseDir = (GetActorLocation() - (DamageCauser->GetActorLocation() + FVector(0.0f, 0.0f, HU_TO_UU(-10.0f)))).GetSafeNormal();
78+
}
79+
else
80+
{
81+
ImpulseDir = DamageEvent.GetImpulse(DamageTaken, this, PawnInstigator).GetSafeNormal();
82+
}
83+
84+
const float SizeFactor = (FMath::Square(HU_TO_UU(32.0f)) * HU_TO_UU(72.0f)) / (FMath::Square(GetCapsuleComponent()->GetScaledCapsuleRadius() * 2.0f) * GetCapsuleComponent()->GetScaledCapsuleHalfHeight() * 2.0f);
85+
86+
float Magnitude = HU_TO_UU(DamageTaken) * SizeFactor * 5.0f;
87+
Magnitude = FMath::Min(Magnitude, HU_TO_UU(1000.0f));
88+
89+
FVector Impulse = ImpulseDir * Magnitude;
90+
bool const bMassIndependentImpulse = !DmgTypeCDO->bScaleMomentumByMass;
91+
float MassScale = 1.f;
92+
if (!bMassIndependentImpulse && GetCharacterMovement()->Mass > SMALL_NUMBER)
93+
{
94+
MassScale = 1.f / GetCharacterMovement()->Mass;
95+
}
96+
if (CapDamageMomentumZ > 0.f)
97+
{
98+
Impulse.Z = FMath::Min(Impulse.Z * MassScale, CapDamageMomentumZ) / MassScale;
99+
}
100+
101+
GetCharacterMovement()->AddImpulse(Impulse, bMassIndependentImpulse);
102+
}
103+
}
104+
54105
void APBPlayerCharacter::ClearJumpInput(float DeltaTime)
55106
{
56-
// Don't clear jump input right away if we're auto hopping or noclipping (holding to go up)
57-
if (CVarAutoBHop->GetInt() != 0 || bAutoBunnyhop || GetCharacterMovement()->bCheatFlying)
107+
// Don't clear jump input right away if we're auto hopping or noclipping (holding to go up), or if we are deferring a jump stop
108+
if (CVarAutoBHop.GetValueOnGameThread() != 0 || bAutoBunnyhop || GetCharacterMovement()->bCheatFlying || bDeferJumpStop)
58109
{
59110
return;
60111
}
61112
Super::ClearJumpInput(DeltaTime);
62113
}
63114

115+
void APBPlayerCharacter::Jump()
116+
{
117+
if (GetCharacterMovement()->IsFalling())
118+
{
119+
bDeferJumpStop = true;
120+
}
121+
122+
Super::Jump();
123+
}
124+
64125
void APBPlayerCharacter::OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PrevCustomMode)
65126
{
66127
if (!bPressedJump)
@@ -90,31 +151,28 @@ void APBPlayerCharacter::OnMovementModeChanged(EMovementMode PrevMovementMode, u
90151

91152
void APBPlayerCharacter::StopJumping()
92153
{
93-
Super::StopJumping();
94-
if (GetCharacterMovement()->bCheatFlying)
154+
if (!bDeferJumpStop)
95155
{
96-
Cast<UPBPlayerMovement>(GetMovementComponent())->NoClipVerticalMoveMode = 0;
156+
Super::StopJumping();
97157
}
98158
}
99159

100160
void APBPlayerCharacter::OnJumped_Implementation()
101161
{
102-
LastJumpTime = GetWorld()->GetTimeSeconds();
103-
if (GetCharacterMovement()->bCheatFlying)
162+
if (MovementPtr->IsOnLadder())
104163
{
105-
MovementPtr->NoClipVerticalMoveMode = 1;
164+
return;
106165
}
107-
else if (GetWorld()->GetTimeSeconds() >= LastJumpBoostTime + MaxJumpTime)
166+
167+
if (GetWorld()->GetTimeSeconds() >= LastJumpBoostTime + MaxJumpTime)
108168
{
109169
LastJumpBoostTime = GetWorld()->GetTimeSeconds();
110170
// Boost forward speed on jump
111171
FVector Facing = GetActorForwardVector();
112-
// Give it its backward/forward direction
113-
float ForwardSpeed;
114172
FVector Input = MovementPtr->GetLastInputVector().GetClampedToMaxSize2D(1.0f) * MovementPtr->GetMaxAcceleration();
115-
ForwardSpeed = Input | Facing;
173+
float ForwardSpeed = Input | Facing;
116174
// Adjust how much the boost is
117-
float SpeedBoostPerc = (bIsSprinting || bIsCrouched) ? 0.1f : 0.5f;
175+
float SpeedBoostPerc = bIsSprinting || bIsCrouched ? 0.1f : 0.5f;
118176
// How much we are boosting by
119177
float SpeedAddition = FMath::Abs(ForwardSpeed * SpeedBoostPerc);
120178
// We can only boost up to this much
@@ -139,7 +197,7 @@ void APBPlayerCharacter::OnJumped_Implementation()
139197
// Boost our velocity
140198
FVector JumpBoostedVel = GetMovementComponent()->Velocity + Facing * SpeedAddition;
141199
float JumpBoostedSizeSq = JumpBoostedVel.SizeSquared2D();
142-
if (CVarBunnyhop->GetInt() != 0)
200+
if (CVarBunnyhop.GetValueOnGameThread() != 0)
143201
{
144202
FVector JumpBoostedUnclampVel = GetMovementComponent()->Velocity + Facing * SpeedAdditionNoClamp;
145203
float JumpBoostedUnclampSizeSq = JumpBoostedUnclampVel.SizeSquared2D();
@@ -163,6 +221,8 @@ void APBPlayerCharacter::ToggleNoClip()
163221

164222
bool APBPlayerCharacter::CanJumpInternal_Implementation() const
165223
{
224+
// UE-COPY: ACharacter::CanJumpInternal_Implementation()
225+
166226
bool bCanJump = GetCharacterMovement() && GetCharacterMovement()->IsJumpAllowed();
167227

168228
if (bCanJump)
@@ -263,21 +323,19 @@ void APBPlayerCharacter::ApplyDamageMomentum(float DamageTaken, FDamageEvent con
263323
}
264324
}
265325

266-
void APBPlayerCharacter::RecalculateBaseEyeHeight() {}
267-
268-
bool APBPlayerCharacter::CanCrouch() const
326+
void APBPlayerCharacter::RecalculateBaseEyeHeight()
269327
{
270-
return !GetCharacterMovement()->bCheatFlying && Super::CanCrouch();
328+
const ACharacter* DefaultCharacter = GetClass()->GetDefaultObject<ACharacter>();
329+
const float OldUnscaledHalfHeight = DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight();
330+
const float CrouchedHalfHeight = GetCharacterMovement()->GetCrouchedHalfHeight();
331+
const float FullCrouchDiff = OldUnscaledHalfHeight - CrouchedHalfHeight;
332+
const UCapsuleComponent* CharacterCapsule = GetCapsuleComponent();
333+
const float CurrentUnscaledHalfHeight = CharacterCapsule->GetUnscaledCapsuleHalfHeight();
334+
const float CurrentAlpha = 1.0f - (CurrentUnscaledHalfHeight - CrouchedHalfHeight) / FullCrouchDiff;
335+
BaseEyeHeight = FMath::Lerp(DefaultCharacter->BaseEyeHeight, CrouchedEyeHeight, UPBUtilityLibrary::SimpleSpline(CurrentAlpha));
271336
}
272337

273-
#if ENGINE_MAJOR_VERSION == 4
274-
void APBPlayerCharacter::RecalculateCrouchedEyeHeight()
338+
bool APBPlayerCharacter::CanCrouch() const
275339
{
276-
if (GetCharacterMovement() != nullptr)
277-
{
278-
constexpr float EyeHeightRatio = 0.8f; // how high the character's eyes are, relative to the crouched height
279-
280-
CrouchedEyeHeight = GetCharacterMovement()->GetCrouchedHalfHeight() * EyeHeightRatio;
281-
}
340+
return !GetCharacterMovement()->bCheatFlying && Super::CanCrouch() && !(MovementPtr->IsOnLadder() || MovementPtr->IsInForcedMove());
282341
}
283-
#endif
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Please sign in to comment.