How would I go about creating a diving system?

What would I do to make a diving system? Body velocity’s don’t really work anymore, so idk how I could make a diving system. Any advice would be appreciated. :smiley:

1 Like

You have to learn how to use the newer mover constraints. They’re the revamped version of the BodyVelocities. They have a tutorial on how you could use them somewhere within the documentation as well, but for this instance (if i’m not mistaking the “diving” system as like mario’s dive), you’ll need to use VectorForce.

With these constraints, you can’t just put them on an unanchored part and it’ll work (like BodyVelocities). Instead, you’ll need an attachment on that part and attach the constraints Attachment0 to that constraint for it to work. Depending on the type of constraint your using, you’ll only need one attachment for it to work.

Luckily, we don’t even need to create an attachment when the player joins; They create a root attachment within the Player.Character's HumanoidRootPart, so we can just use that to attach to the VectorForce.

So with this being said, this is actually how the script could work. (Rough draft, never tested; made for an example)

-- These are two separate scripts. You'll need to make a script to handle
-- the Remote:InvokeServer(), so that the dive replicates to all of the
-- players within the game. The Remote also needs to be a RemoteFunction.

-- Local Script within the StarterCharacterScripts
local ContextActionService = game:GetService("ContextActionService")

local DiveRemote = game.ReplicatedStorage.Dive

local Character = script.Parent
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local RootAttach = HumanoidRootPart:FindFirstChildOfClass("Attachment")

local debounce = false -- so that they don't spam the dive button
local diveForce = 10

local function Dive(name: string, state: Enum.UserInputState, input: InputObject)
    if state == Enum.UserInputState.Begin and not debounce then
        debounce = true
        DiveRemote:InvokeServer(RootAttachment, HumanoidRootPart, diveForce)
        debounce = false
    end
end

ContextActionService:BindAction("DiveBind", Dive, true, Enum.KeyCode.LeftShift)

-- Script within ServerScriptService
local Remote = game.ReplicatedStorage:WaitForChild("DiveRemote")

local function PlayerDive(attach, root, force)
    local DiveForce = Instance.new("VectorForce")
    DiveForce.Attachment0 = attach
    DiveForce.Force = root.CFrame.LookVector * force
    DiveForce.RelativeTo = Enum.ActuatorRelativeTo.World
    DiveForce.ApplyAtCenterOfMass = true
    DiveForce.Parent = root
    
    root.AssemblyLinearVelocity += Vector3.new(0, 25, 0) -- like in mario 64, 
    -- they go up a little bit

    -- You'd also want to check when the player hits the ground and then delete
    -- the force, but this is just a quick example of how you could implement
    -- the VectorForce. For now, we'll just wait an x amount of seconds.
    task.wait(5)
    return true
end

Remote.OnServerInvoke = PlayerDive
5 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.