After a lot of work, I managed to create the system I wanted, however, it can be a little complicated and I am sure could be optimised if I knew more about the physics going in the back end.
First, I am using a raycast to shoot a ray from the humanoid root part directly down. I am using this to find the first part underneath the player to align the position.
Then I make a variable, which I will refer as yDirection, and set it to the Y position of the humanoid root part minus the distance of the raycast
Then I set the yDirection to the yDirection plus the size of the character divided by 2:
yDirection = yDirection + character:GetExtentsSize()/2
Then I create a AlignPosition with the following properties:
local pAlignPos = Instance.new("AlignPosition",character.HumanoidRootPart)
pAlignPos.Attachment0 = pAttachment
pAlignPos.ApplyAtCenterOfMass = false
pAlignPos.RigidityEnabled = false
pAlignPos.Mode = Enum.PositionAlignmentMode.OneAttachment
pAlignPos.Responsiveness = 5
pAlignPos.MaxForce = 500000 -- Could be made smaller, I am not too sure
pAlignPos.MaxVelocity = math.huge
pAlignPos.Position = Vector3.new(character.HumanoidRootPart.Position.X,yDirection,character.HumanoidRootPart.Position.Z)
Then I create a counter vector force with the following properties:
local pVectorForce = Instance.new("VectorForce",character.HumanoidRootPart)
pVectorForce.Attachment0 = pAttachment
pVectorForce.Force = Vector3.new(0,-500000,0)
With this, it creates the affect of aligning the position of the X and Z axis whilst still allowing gravity to affect the character
There is one problem being that the final yDirection is about 0.1 units off, I am not too sure how to fix this but if I figure out I will reply later