Last active
August 4, 2024 09:42
-
-
Save trentpolack/edefe1c72161f57dc188dd0c746a606e to your computer and use it in GitHub Desktop.
The "Fun" to be had (i.e. a big rant) in writing a general-purpose physical movement component (compound colliders representing static and skeletal meshes and more, but still interacting with the world as a physical entity). NOTE: All comments in this gist are by me.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Comments are left by me, not from the code. | |
// Because why not have a default set or make the method abstract or, really, anything but this. Luckily no one would ever | |
// think to use ::GetMaxSpeed as a divisor or anything. | |
inline float UMovementComponent::GetMaxSpeed() const | |
{ | |
return 0.f; | |
} | |
// FUN FACT: UMovementComponent defines a plethora of methods for managing the maximum speed of a component. It does not, | |
// however, actually have a maximum speed class member. | |
// I'm not sure this really handles an impact. Of any kind. Anywhere. Ever. | |
void UMovementComponent::HandleImpact(const FHitResult& Hit, float TimeSlice, const FVector& MoveDelta) | |
{ | |
} | |
// Seriously, what is with just leaving methods empty with no obvious way to notify developers. | |
void UMovementComponent::AddRadialForce(const FVector& Origin, float Radius, float Strength, enum ERadialImpulseFalloff Falloff) | |
{ } | |
void UMovementComponent::AddRadialImpulse(const FVector& Origin, float Radius, float Strength, enum ERadialImpulseFalloff Falloff, bool bVelChange) | |
{ } | |
// Even UE4's basic humanoid movement controller (a 10k line CPP file) likes this whole "hope they don't use that and expect | |
// it do anything" philosophy. | |
void UCharacterMovementComponent::OnMovementUpdated(float DeltaTime, const FVector& OldLocation, const FVector& OldVelocity) | |
{ | |
// empty base implementation, intended for derived classes to override. | |
} | |
// Yes, again, another silently empty method, but it's made more confusing since ::ShouldJumpOutOfWater and ::CheckWaterJump both | |
// are fully-implemented methods. | |
void UCharacterMovementComponent::JumpOutOfWater(FVector WallNormal) {} | |
// This is just accurate, no one should ever "catch air". | |
bool UCharacterMovementComponent::ShouldCatchAir(const FFindFloorResult& OldFloor, const FFindFloorResult& NewFloor) | |
{ | |
return false; | |
} | |
// Anyway, there's more like this (and some generally horrifying code conventions), but the real issue is that UCharacterMovementComponent | |
// is essentially just a really, really overwrought implementation to handle a specific type of pawn/actor: basic primitives | |
// and humanoids. UCharacterMovementComponent is, really, just an overly complex state machine for each type of movement (running, | |
// ducking, falling, jumping, crouching, walking, swimming, etc.). | |
// | |
// This means that, really, deriving a custom movement component from it is not only bringing along a *lot* of additional friends | |
// for the ride, but also that its implementation is so rigid in its use cases that whatever it offers would have to be intensely | |
// modified anyway (as I've been doing. this is the third or fourth pass). | |
// | |
// TL;DR: As *wonderful* as UE4's codebase is on the core engine/renderer (and many, many other areas), as far as its "gameplay | |
// framework" is concerned, there's really just not much there (at least, in my mind) that makes life easier for C++ developers. | |
// Especially given the dearth of documentation on the more obscure classes/components/data structures you'll end up needing | |
// to use along the way. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
1 person finds this funny
I was just going throug async physics character movement of UE5 and was buffled by the amount of TODOs and things left unimplemented. I will inherit from UPawnMovementComponent and hope for the best! 😆