There are many ways to approach this, however this is what I’d do.
First, I’d store the character as a variable, then their humanoid and humanoidrootpart. Then, I’d create a variable to something like DiveAnimation which will play the players dive animation when I use DiveAnimation:Play(). After that, I would create a debounce variable and initialize it as true. Debounce is like the cooldown for the script, you probably don’t want the user to dive a hundred times in a second. After the debounce, I’ll declare 2 number variables: diveSpeed (how far they dive forward) and the diveHeight (how high they travel whilst diving). Then, I’ll use game:GetService(“UserInputService”).InputBegan(Input, IsChatting) to create an event for when the user pressed a key (Input represents the key code the user pressed, and IsChatting is a boolean on whether the user is chatting or interacting with any Roblox CoreGui elements (Menu, Backpack, Etc.). Then, I’ll make an if statement checking the following conditions; Is the Input the user inputted equal to Enum.Keycode.E, and is the debounce true, and is the user NOT IsChatting. Then, when all these conditions are true, the player can begin the dive. I’d start by setting debounce to false so that the player can’t spam E, and use Humanoidrootpart:ApplyImpulse(Humanoidrootpart:GetAssemblyMass() * Humanoidrootpart.CFrame.LookVector * diveSpeed + Vector3.new(0, diveHeight, 0))
After that, I’d do DiveAnimation:Play() and add a wait which represents the cooldown for the dive. After the wait, set debounce back to true so the player can press E again. Hope this helped!