Air walk movement mechanic

Recently I came across a fighting game called Psychis Battlegrounds, which features a very interesting mechanic: air walking.


As you can see in the video, to enter the air walk state, you must first double jump and then hold the spacebar, allowing you to remain in air and walk, as if you were still on the ground.

Now, this is something I’ve never really seen on Roblox before so I was curious to figure out how it was done and I got to work, coming up with 3 possible ways it could be done:

  1. After double jumping and when in air, spawn invisible parts, client-side, right under the player character, allowing it to walk on a solid surface, which gives the illusion of walking mid-air: this probably what most people would suggest. While this is a viable method, I think it’s a bit inelegant, because it seems kinda unoptimized and would probably be jittery, resulting in the character to sort of “wobble” while stepping on each part. Unless there is some way to get exactly the position right under the character’s, allowing to create a perfectly even surface that gives the illusion of walking on air without possibly glitching thru.
    Didn’t attempt this method because it’s my least favourite one and I wasn’t even sure on how to proceed.

  2. Messing around with Humanoid States: basically, something like setting the Humanoid state to Running while Freefalling, possibly mantaining the character mid-air? I’m not sure.
    Again, didn’t try this one because I wasn’t sure on what to do exactly. It doesn’t exactly make sense since humanoid states don’t seem to affect physics.

  3. Using LinearVelocity or VectorForce to contrast the workspace’s gravity: this is the one method I tried, with little to no successful results. Essentially, I parented a LinearVelocity\VectorForce (tried both, I suck at physics. I believe LinearVelocity is the correct one, because I want to mantain the same force, whereas VectorForce causes the acceleration to increase), setting the vector’s force\velocity to Vector3.new(0,workspace.Gravity,0).
    What happened was that it would just shoot up the character in air, making it impossible to walk.
    I also tried applying some simple physics, such as:

local hrp : Part = script.Parent.PrimaryPart
local hum = script.Parent:FindFirstChildOfClass("Humanoid")
local vel = Instance.new("LinearVelocity")
local att = script.Parent.PrimaryPart:FindFirstChild("RootAttachment")

vel.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
vel.Attachment0 = att

local mass = hrp.AssemblyMass
local gravity = workspace.Gravity
local weight = mass * gravity

vel.MaxForce = weight
vel.VectorVelocity = Vector3.new(0,weight + gravity,0)
vel.Parent =  script.Parent.PrimaryPart

Basically I tried to take into account the character’s mass, but it still shoot up the character in air.
I’m also 99% sure that the formulas are wrong because, again, I suck at physics.

Any feedback would be appreciated.

3 Likes

The simplest way I think is clearly option one. But you need only create a single plane. The “air floor” plane you create to walk on can be set to be only collidable by the player and large enough to support any direction for the period of time the air walk is active. Then simply remove the floor until its needed again. Another possible option could be the plane lock constraint.

Something along this line could get you the position to place the plane when its activated.

cframeUnderChar = char:GetPivot() * CFrame.new(0, -char.humanoid.HipHeight, 0)
2 Likes

can’t you do something like

local downForce = - part:GetMass() * workspace.Gravity + 300 --(lower = lower gravity, higher is higher gravity)
		local force = -downForce
		part.Value.Value = plr.Name
		local bodyForce = Instance.new("BodyForce")
		bodyForce.Force = Vector3.new(0,force,0)
	bodyForce.Parent = part
1 Like

No, not really, because:

  1. BodyForce is deprecated
  2. Doesn’t work
  3. What is that part.Value.Value supposed to be for?

Yeah, this is what I was doing just now. Idk why I thought I’d have to spawn a new part each step, one plane is fine. A bit gimmicky but it gets the work done.
I guess that would have to suffice, but I’d appreciate some other ideas, maybe physics-based solutions.

Didn’t think about it, I’ll try to check it out, thanks! Do you have the link to the documentation? I can’t find it on google

mb the value is just ripped from my script
i guess you can change the bodyforce to something else, what part did you put the bodyforce to? you might have to do it to the whole player character

HumanoidRootPart, it’s where handles the whole character’s physics are applied

I’m guessing they increased the humanoid’s hip height and then made a slower running animation in
mid-air but it might be something else too.

Nope cuz when you increase the hip height, the character walks weird\is kinda wobbly, so I don’t think that’s how they did it tbh…

Bump, hoping for some more ideas. The part underneat the character, while not my favourite solution, seems to be the way to go currently

You can def do this with vector forces and physics but its a tricky balancing act because while a force equal to gravity will make something stationary float or hover, the moment it moves its going to get crazy on you. Gravity causes an acceleration so you would need to constantly counter that acceleration at any moment while still allowing for some slight variations.

Now that I’m thinking about it you might be able to link up ApplyImpulse() method to the character walk/run animation so an impulse is applied each step. Impulse is like a short burst of force. If I was going to try this I would create a custom walk/run animation and add animation events on each foot step frame then use that event to fire off the impulse. Its still going to be tricky though.

I want 2% royalty for the idea lmao, jk