# Convert Rigidbody.AddForceAtPosition to Unity Physics.

I’m writing a buoyancy system for Unity Physics by converting a rigidbody one I got.

I’m not sure how to convert this. I can’t find anything on how to add force at position.

`````` // apply drag relative to water
var forcePosition = _rb.position + _forceHeightOffset * Vector3.up;
_rb.AddForceAtPosition(Vector3.up * Vector3.Dot(Vector3.up, -velocityRelativeToWater) * _dragInWaterUp, forcePosition, ForceMode.Acceleration);
_rb.AddForceAtPosition(transform.right * Vector3.Dot(transform.right, -velocityRelativeToWater) * _dragInWaterRight, forcePosition, ForceMode.Acceleration);
_rb.AddForceAtPosition(transform.forward * Vector3.Dot(transform.forward, -velocityRelativeToWater) * _dragInWaterForward, forcePosition, ForceMode.Acceleration);
``````

Unity.Physics.Extensions has some extension methods for applying impulses. To apply forces, use force * deltaTime to get impulse

``````using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Physics.Extensions;
using Unity.Transforms;

[UpdateBefore(typeof(BuildPhysicsWorld))]
public class ImpulseAtPointSystem : SystemBase
{
protected override void OnUpdate()
{
Entities.ForEach((DynamicBuffer<ImpulseAtPoint> impulses, ref PhysicsVelocity velocity, in PhysicsMass mass, in Translation translation, in Rotation rotation) =>
{
NativeArray<ImpulseAtPoint> impulseArray = impulses.AsNativeArray();
for (int i = 0; i < impulseArray.Length; i++)
{
velocity.ApplyImpulse(mass, translation, rotation, impulseArray[i].Impulse, impulseArray[i].Point);
}
impulses.Clear();
}).ScheduleParallel();
}
}
``````

Thanks.

I did this.

``````//Do Physics
if (_inWater)
{
forces.Clear();
forces.Add(Vector3.up * Vector3.Dot(Vector3.up, -velocityRelativeToWater) * _dragInWaterUp);
forces.Add(localToWorld.Right * Vector3.Dot(localToWorld.Right, -velocityRelativeToWater) * _dragInWaterRight);
forces.Add(localToWorld.Forward * Vector3.Dot(localToWorld.Forward, -velocityRelativeToWater) * _dragInWaterForward);

var forcePosition = position + _forceHeightOffset * Vector3.up;

for (int i = 0; i < forces.Count; i++)
AddForceAtPosition(ref physicsMass, ref translation,ref rotation, ref physicsVelocity, PhysicsWorldExtensions.GetRigidBodyIndex(physicsWorld, entity), forces[i],forcePosition, ForceMode.Acceleration);
}

private void GetImpulseFromForce(ref PhysicsMass mass, float3 force, UnityEngine.ForceMode mode, float timeStep, out float3 impulse, out PhysicsMass impulseMass)
{
var unitMass = new PhysicsMass { InverseInertia = new float3(1.0f), InverseMass = 1.0f, Transform = mass.Transform };

switch (mode)
{
case UnityEngine.ForceMode.Force:
// Add a continuous force to the rigidbody, using its mass.
impulseMass = mass;
impulse = force * timeStep;
break;
case UnityEngine.ForceMode.Acceleration:
// Add a continuous acceleration to the rigidbody, ignoring its mass.
impulseMass = unitMass;
impulse = force * timeStep;
break;
case UnityEngine.ForceMode.Impulse:
// Add an instant force impulse to the rigidbody, using its mass.
impulseMass = mass;
impulse = force;
break;
case UnityEngine.ForceMode.VelocityChange:
// Add an instant velocity change to the rigidbody, ignoring its mass.
impulseMass = unitMass;
impulse = force;
break;
default:
impulseMass = mass;
impulse = float3.zero;
break;
}
}

private void AddForceAtPosition(ref PhysicsMass physicsMass, ref Translation translation,ref Rotation rotation, ref PhysicsVelocity velocity, int entityIndex, float3 force, float3 position, ForceMode mode = ForceMode.Force)
{

GetImpulseFromForce(ref physicsMass,force, mode, deltaTime, out float3 impulse, out PhysicsMass impulseMass);
velocity.ApplyImpulse(impulseMass, translation, rotation, impulse, position);
}
``````
1 Like