Server:

--[!] SERVER
-- globals
local ROLL_SPEED = 100 -- we can change these two for the speed/amount of time we roll
local ROLL_TIME  = 1

-- private
local create = function (obj)
	obj = Instance.new(obj)
	return function (props)
		for prop, val in next, props do
			obj[prop] = val
		end
		return obj
	end
end

local isAlive = function (Player)
	local char = Player.Character
	if not char or not char:IsDescendantOf(game.Workspace) or not char:FindFirstChild "Humanoid" or char.Humanoid:GetState() == Enum.HumanoidStateType.Dead then
		return
	end
	return true
end

-- set up
local remote = create "RemoteEvent" {
	Name   = "RollRemote";
	Parent = game:GetService('ReplicatedStorage');
}

-- public
local rolling = { }
remote.OnServerEvent:connect(function (player, vec)
	if not vec or not typeof(vec) == "Vector3" or vec.magnitude > Vector3.new(1, 1, 1).magnitude then
		return -- the magnitude check here is to make sure that players aren't sending you vectors that are greater than the unit vector of their movement direction
	end
	if isAlive(player) and not rolling[player] then -- we're checking to see if they're in the 'rolling' table to ensure they're not spamming it, which would create multiple bodyvelocities
		local root, hum = player.Character:FindFirstChild 'HumanoidRootPart', player.Character:FindFirstChild 'Humanoid'
		if root and hum then
			local prevWalk = hum.WalkSpeed

			rolling[player] = true
			hum.WalkSpeed = 0 -- we can remove their walkspeed here to stop them from being able to move whilst they roll other than through their bodyvelo

			local velo = create "BodyVelocity" {
				Parent      = root;
				MaxForce = Vector3.new(1, 0, 1) * 10000;
			}
			velo.Velocity = vec * ROLL_SPEED
			delay(ROLL_TIME, function () -- after we've rolled for our preset time, we can reset everything
				if velo then
					velo:Destroy()
					hum.WalkSpeed = prevWalk
				end
				rolling[player] = false
			end)
		end
	end
end)

Client:

--[!] CLIENT
local Player = game.Players.LocalPlayer
repeat wait() until Player.Character
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")

-- environment
local Controller   = require(Player.PlayerScripts:WaitForChild("PlayerModule")):GetControls()
local InputService = game:GetService('UserInputService')
local RollRemote   = game:GetService('ReplicatedStorage'):WaitForChild 'RollRemote'

-- variables
local Anim = Instance.new("Animation")
Anim.AnimationId = "rbxassetid://7731516813"
local animationTrack = Humanoid:WaitForChild("Animator"):LoadAnimation(Anim)

-- private
local getMoveVector = (function ()
	return Controller:GetMoveVector()
end)

local getRelativeMoveVector = (function ()
	local vec = getMoveVector()
	return game.Workspace.CurrentCamera.CFrame:inverse():VectorToObjectSpace(vec)
end)

-- init
InputService.InputBegan:connect(function (input, gameProcessed)
	if gameProcessed then
		return
	end
	if input.UserInputType == Enum.UserInputType.Keyboard then
		local key = tostring(input.KeyCode):sub(14)

		if key == "LeftControl" then
			RollRemote:FireServer(getRelativeMoveVector())
			animationTrack:Play()
		end
	end
end)

1 comment

0

I think it's client side, maybe you should try adding a look around init.