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