Okay, so for example ,a roll that is in the direction the camera was facing when the roll key was pressed, moving the character in the heartbeat runservice event:
You need to track when a roll started, the direction to roll in, the roll length and the time since the last heartbeat.
local Humanoid = script.Parent:WaitForChild("Humanoid") --CharacterScripts copied to Char on load, wait for Humanoid
local RootPart = script.Parent:WaitForChild("HumanoidRootPart")
local RollTrack = Humanoid:LoadAnimation(game.ReplicatedStorage:WaitForChild("RollAnimation"))
repeat wait() until RollTrack.Length ~= 0
--Wait for the animation to load properly
local RollStartTime = 0
local RollDirection = Vector3.new()
local RollMult = 15/RollTrack.Length --15 studs / AnimLength
use UserInputService to check for when the user presses the roll key:
InputService.InputBegan:Connect(function(input,processed)
if input and not processed then
--If roblox has not handled the input (GUI textbox, esc key, alt tab etc, gui buttons clicked)
if input.UserInputType == Enum.UserInputType.Keyboard then
--if it is keyboard input
if input.KeyCode == RollKey and tick()-RollStartTime > .75 then
--Do a roll
RollTrack:Play()
RollStartTime = tick()
local dirVec = workspace.CurrentCamera.CFrame.LookVector
RollDirection = (dirVec*Vector3.new(1,0,1)).unit
--normalise in horizontal plane
end
end
end
end)
In the heartbeat calculate the time since the last for a delta, dT, and apply the roll CFrame to the HumanoidRootPart to move the character.
local LastBeat = tick()
RunService.Heartbeat:Connect(function()
local dT = tick()-LastBeat
LastBeat = tick()
if tick()-RollStartTime < .75 then
RootPart.CFrame = CFrame.new(RollDirection*dT*RollMult) * RootPart.CFrame
end
end)
The RollDirection vector is in world space, so just apply it before the RootPart CFrame, to offset the world grid rather than transform the rootpart cframe. RollMult will be the number of studs to move by divided by the animation length.