# Limit the velocity of a Networked Physics object. 

**URL:** <https://forums.unrealengine.com/t/limit-the-velocity-of-a-networked-physics-object/2441952>\
**Category:** Multiplayer & Networking\
**Tags:** Networking, async, unreal-engine, Physics, CPP, question\
**Created:** [April 5, 2025, 9:18pm UTC](https://forums.unrealengine.com/t/limit-the-velocity-of-a-networked-physics-object/2441952 "2025-04-05T21:18:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lealander](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Lealander](https://forums.unrealengine.com/u/Lealander)\
**Post date:** [April 5, 2025, 9:18pm UTC](https://forums.unrealengine.com/t/limit-the-velocity-of-a-networked-physics-object/2441952/1 "2025-04-05T21:18:49Z")

</div>

Hello,  
As the the topic states I am trying to limit the velocity of a Networked Physics component. I am using a NetworkPhysicsComponent’s AsyncPhsyicsTickComponent method to apply forces based on the player’s input, ie:

```auto
void UVesselMovementComponent::AsyncPhysicsTickComponent (float DeltaTime, float SimTime)
{
   Super::AsyncPhysicsTickComponent(DeltaTime, SimTime);
...

    // Apply inputs    
    if (VesselInputs.bAreBoostersActive)
	{
		FVector boosterForce = HullMesh->GetForwardVector() * BoosterForce * BodyInstance->GetBodyMass();
		HullMesh->AddForce(boosterForce);
	}

... 
    // Limit velocity ~ this seems to wipe out any previous applied forces
    if(HullMesh->GetPhysicsLinearVelocity().Length() > 500)
	{
		FVector limitedVelocity = UKismetMathLibrary::ClampVectorSize(HullMesh->GetPhysicsLinearVelocity(), 0, 500);
		HullMesh->SetPhysicsLinearVelocity(limitedVelocity);
	}
}

```

However, when my speed limit is exceeded, hard setting the velocity seems to scrap any applied forces (including ones that would push the object in the other direction) which results in the object getting locked in to the max velocity vector. I almost need a post async tick function to run after the new forces have been applied.

Does anyone know how to limit the velocity of a networked physics object using the async physics tick? I believe it needs this in order for correct resimulation.

I was able to get this to work blueprints outside of networking via applying the forces in on input actions, and limiting the velocity in the base blueprint Tick, but that isn’t networked and I have been re-writing components to get multiplayer working.

Also, the guide I was following applied forces to the core component’s RigidBodyHandle via getting it from GetPhysicsThread(), like this:

```auto
if (const auto Handle = BodyInstance->ActorHandle)
	{
		RigidBodyHandle = Handle->GetPhysicsThreadAPI();
	}

```

Where RigidBodyHandle is: Chaos::FRigidBodyHandle\_Internal\*  
And BodyInstance is: FBodyInstance\*  
However I’m just directly applying the forces to the component that the RigidBodyHandle wraps.  
I’m was unable to find a difference in results from testing. Does anyone know the differences there?

Im using Unity 5.5

Thanks for your time.

---

<div class="post-metadata">

**Author:** ![Lealander](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@Lealander](https://forums.unrealengine.com/u/Lealander)\
**Post date:** [April 12, 2025, 9:03pm UTC](https://forums.unrealengine.com/t/limit-the-velocity-of-a-networked-physics-object/2441952/2 "2025-04-12T21:03:14Z")

</div>

Updating because I figured it out after talking to ChatGPT, dusting off the ol’ physics text books, and reading some other blogs.

Firstly, some Unreal book keeping:

- Make sure your physics settings are set correctly in Project Settings \> Physics \> Framerate:  
 ![Screenshot 2025-04-12 132555](https://d3kjluh73b9h9o.cloudfront.net/original/4X/b/a/e/baed30ed35dd3ec9050d6f7daa437f281f642dd1.png)  
I found these settings to be smooth, I’ll need to tinker more with them when I understand them better.
- In `AsyncPhysicsTickComponent` be sure to apply forces to the RigidBodyHandle (on the physics thread) and not the actual RigidBody the handle is representing on the main thread.

Onto solving the problem: Limiting speed by adjusting applied force, with the basic force formula: `Force = Mass * Acceleration`  
Effectively, we want acceleration to approach 0 as we approach our max speed, and have acceleration respect our arbitrary MaxSpeed.

We can determine the amount of acceleration we need by:  
`Acceleration = DeltaVelocity/DeltaTime`  
DeltaVelocity = `(InputVelocity - CurrentVelocity) / DeltaTime`  
InputVelocity = `InputDirection * MaxSpeed`

Unfortunately, CurrentVelocity isn’t that simple ~ it needs to be the Current Velocity’s _contribution_ to the target InputVelocity. For example, imagine our InputVelocity is(4,0) and our CurrentVelocity is(1,3), current Velocity is already contributing 1unit of velocity, so we would only need an addition 3 units of speed.  
We need to _project_ CurrentVelocity onto our desired InputVelocity which gives us a magnitude of CurrentVelocity already done by InputVelocity. Lets call this our ContributingSpeed.  
From our example, projecting CurrentVelocity onto InputVelocity, our ContributingSpeed is:

```auto
= Dot(CurrentVelocity(1,3), InputVelocity(4,0)) / Magnitude(InputVelocity(4,0)
= ((1*4) + (3*0) ) / Sqrt(4^2+0^2)
= (4+0)/sqrt(16)
= 4/4
= 1

```

This means that our current velocity is contributing 1 unit of speedtowards our InputVelocity target speed already. Some notes:

- the result is NOT a vector, its a magnitude.
- if the result is NEGATIVE, our current velocity is in an opposing direction to our InputForce
- if the result is LARGER than our InputVector magnitude, we are already traveling _faster_ in that direction than our input wants us to go.

Next we want to consider the previous notes and determine the % of InputVector still needed to hit our target acceleration, we can call this % our ContributionFactor, which should be between 0 and 1 (0 no more velocity is needed, 1 need full possible velocity):

```auto
if (ContributingSpeed < 0 )
  // current velocity is opposing our input so we want to apply our full possible acceleration.  
  ContributionFactor = 1 
else
  // Want to see how velocity is still needed, but limit it in the event we are already traveling faster than desired.
  ContributionFactor = 1 - Clamp(ContributingSpeed/Magnitude(InputVector), 0, 1)

```

Now, we can use ContributionFactor on our InputVelocity to determine our needed Acceleration, and clamp it by our thruster’s max force as needed:

```auto
Acceleration = InputVelocity * ContributionFactor / DeltaTime
LimitedAcceleration = Acceleration.ClampMagnitude(ThrusterForce*Mass);
RigidBody.AddForce(LimitedAcceleration * Mass)

```

The C++ Unreal code is:

```auto
void UGameMovementComponent::AsyncPhysicsTickComponent (float deltaTime, float simTime)
{
	Super::AsyncPhysicsTickComponent(deltaTime, simTime);

	// Setup
	if (const auto Handle = BodyInstance->ActorHandle)
	{
		RigidBodyHandle = Handle->GetPhysicsThreadAPI();
		if (!RigidBodyHandle) return;
	}
	const FVector inputDirection = FVector::UpVector; // This would come from the player's input struct
	const float mass = 1000;
	const float maxSpeed = 750;
	const float thrusterForce = 3000;

	// Acceleration Based.
	const FVector InputVelocity = inputDirection * maxSpeed;

	// Determine the current velocity contributions
	const float currentVelocityContribution = RigidBodyHandle->V().Dot(InputVelocity)/InputVelocity.Length(); // Note, RigidBodyHandle->V() is the current velocity of the rigid body state, thread bound and stuff.
	const float velocityContributionFactor = currentVelocityContribution < 0.0 ? 1.0 : 1.0 - FMath::Clamp(currentVelocityContribution/InputVelocity.Length(), 0.0, 1.0);

	// Determine the target 
	const FVector targetAcceleration = inputDirection * velocityContributionFactor / deltaTime;
	const FVector limitedAcceleration = targetAcceleration.GetClampedToMaxSize(thrusterForce * mass);
	
	const FVector appliedForce = limitedAcceleration * mass * deltaTime;
	RigidBodyHandle->AddForce(appliedForce, true);
}

```

Here’s a video of it in action. Thrusters visually activate when force/input is being applied. Note the continued drift/velocity:

Some final notes:

1. This applies force in the direction of the input, it does not _redirect_ the object to fly towards the input. Meaning, imagine you start moving directly forward, then apply input directly right. In this implementation you would be traveling up AND right. If you want to use input to redirect current velocity to match the input, you need to replace the “contributing velocity” stuff with current velocity in acceleration, ie:` Acceleration = (InputVelocity - CurrentVelocity) / DeltaTime`. This would effectively give you an opposing/corrective vector to apply force on.
2. This implementation allows you to exceed max velocity, just like from 1. You can thrust straight, then thrust right, and you would continue your straight-ward velocity. This is by design ~ I’m trying to do an _arcady_ feel to space flight where you can have strong boosters that wont take you up 1000’s of km/h. Also, it allows for a faster ship to ‘push’ a slower ship which should help keep the sandbox feeling, I hope.

Hope this helps someone in the future.

---

<div class="post-metadata">

**Author:** ![system](https://d3kjluh73b9h9o.cloudfront.net/original/4X/7/1/3/713c9d3f58553f0de89543d76a8a3a2779dc9fa4.png) [@system](https://forums.unrealengine.com/u/system)\
**Post date:** [May 12, 2025, 9:03pm UTC](https://forums.unrealengine.com/t/limit-the-velocity-of-a-networked-physics-object/2441952/3 "2025-05-12T21:03:29Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
