I’m trying to figure out an odd bug that’s occuring on my project. It seems like opposite forces aren’t canceling out like they should, causing the agent to move around in sporadic cyclic patterns. The goal is to use AddForceAtLocation to simulate buoyancy by calculating the buoyant force, and applying it to the center of volume, and gravity to the center of mass. This was working in unreal 4.27 but when we moved to UE5.3 we saw this bug begin to occur. I can’t find any reason from the documenation, but assume something with the changed physics engine and our code is causing this to break.
I verified with log statements that the force vectors are equal and opposite.
FVector ActorLocation = GetActorLocation();
FRotator ActorRotation = GetActorRotation();
// Check to see how underwater we are
FVector* points = SurfacePoints.GetData();
int count = 0;
for(int i=0;i<NumSurfacePoints;i++){
FVector p_world = ActorLocation + ActorRotation.RotateVector(points[i]);
if(p_world.Z < SurfaceLevel)
count++;
}
float ratio = count*1.0 / NumSurfacePoints;
// Get and apply Buoyant Force
float BuoyantForce = Volume * Gravity * WaterDensity * ratio;
FVector BuoyantVector = FVector(0, 0, BuoyantForce);
BuoyantVector = ConvertLinearVector(BuoyantVector, ClientToUE);
// BuoyantVector = GetActorRotation().RotateVector(BuoyantVector);
FVector COB_World = ActorLocation + ActorRotation.RotateVector(CenterBuoyancy + OffsetToOrigin);
// DrawDebugLine(GetWorld(), COB_World, COB_World + BuoyantVector, FColor::Green, false, 1./30, ECC_WorldStatic, 3);
RootMesh->AddForceAtLocation(BuoyantVector, COB_World);
UE_LOG(LogHolodeck, Warning, TEXT("Buoyant Force x: %f y: %f z: %f"), BuoyantVector.X, BuoyantVector.Y, BuoyantVector.Z);
FVector GravityVector = ConvertLinearVector(FVector(0, 0, -Gravity*MassInKG), ClientToUE);
GravityVector = GetActorRotation().RotateVector(GravityVector);
RootMesh->AddForceAtLocation(GravityVector, RootMesh->GetCenterOfMass());
UE_LOG(LogHolodeck, Warning, TEXT("Gravity Force x: %f y: %f z: %f"), GravityVector.X, GravityVector.Y, GravityVector.Z);