You might be able to spawn a small invisible platform under the player’s feet which updates it’s CFrame to constantly follow the player in all directions.
As a rough pseudo-code guide, you could use these functions:
-- some variables you want set up
local airwalking = false
local airwalkPlatform = nil
-- call this when the player starts their airwalk
function airwalkStart()
airwalking = true
airwalkPlatform = Instance.new("Part")
airwalkPlatform.Anchored = true
airwalkPlatform.Transparency = true
airwalkPlatform.Size = Vector3.new(4,1,4)
end
-- call this when the player completes the airwalk
function airwalkEnd()
airwalking = false
airwalkPlatform:Destroy()
end
-- you will need some way to update the part's position on each Physics Step
game:GetService("RunService").Heartbeat:Connect(function()
if airwalking and airwalkPlatform ~= nil then
--The -3.5 is determined by the distance from the ground to the position of the HumanoidRootPart, plus half of the height of the part itself as defined in airwalkStart()
airwalkPlatform.CFrame = CFrame.new(character.HumanoidRootPart.Position + Vector3.new(0,-3.5,0))
end
end)
If you had any issues with the invisible part colliding with unwanted things, such as unanchored objects or other players, you can set up Collision Groups to mitigate that issue. It should also be fairly easy to add your desired effects and graphics as needed.