:ApplyImpulse() only works after some time

  1. What do you want to achieve?
    I want to make a custom skateboard system
  2. What is the issue?
    Skateboard can’t move around the first minute
  3. What solutions have you tried so far?
    I have no idea what could be causing this. I didn’t see any people with this issue before.

Here’s my code (unfinished):

local Players = game:GetService("Players")
local InputServ = game:GetService("UserInputService")
local plr = Players.LocalPlayer
local playerModule = require(plr.PlayerScripts:WaitForChild("PlayerModule"))
local controls = playerModule:GetControls()

controls:Disable()

plr.CharacterAdded:Wait()

local function weld(part0 : BasePart, part1 : BasePart)
	if (not part0:IsA("BasePart")) or (not part1:IsA("BasePart")) then --NOTE: I used brackets just because I don't know the operator priority
		error("Can't weld non BasePart objects")
	end
	
	local weld = Instance.new("Weld")
	
	weld.Part0 = part0
	weld.Part1 = part1
	
	weld.C0 = part0.CFrame:Inverse()
	weld.C1 = part1.CFrame:Inverse()
	
	weld.Parent = part0
	return weld
end

local function attachSkate(plrChar : Model, skate : Model)
	local leftLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")
	print(leftLeg)
	
	plrChar:MoveTo(plrChar.HumanoidRootPart.Position + Vector3.new(0, 3, 0))
	skate:MoveTo(leftLeg.Position - Vector3.new(0, leftLeg.Size.Y / 2, 0))
	
	weld(leftLeg, skate.Cube)
end

local function moveSkate(plrChar : Model)
	local root = workspace.Skateboard.PrimaryPart
	root:ApplyImpulse((CFrame.new(root.AssemblyLinearVelocity) * CFrame.new(0, 0, -5 * workspace.Gravity)).Position)
	local leftLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")
	if leftLeg and not leftLeg:FindFirstChild("Weld") then
		attachSkate(plrChar, workspace.Skateboard)
	end
end

InputServ.InputBegan:Connect(function(key)
	print(key.KeyCode.Name)
	if key.KeyCode == Enum.KeyCode.W then
		moveSkate(plr.Character)
	end
end)

Please help me.

1 Like

You can try this not sure if it will work but it should change the velocity of the skateboard directly.

local function moveSkate(plrChar)
	local root = workspace.Skateboard.PrimaryPart
	local leftLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")

	if leftLeg then
		attachSkate(plrChar, workspace.Skateboard)

		-- Calculate the direction based on the left leg's orientation
		local direction = leftLeg.CFrame.LookVector * -5 -- Adjust the speed as needed

		-- Set the velocity of the skateboard's PrimaryPart
		root.AssemblyLinearVelocity = Vector3.new(direction.X, 0, direction.Z)
	end
end

I’d assume a skateboard is usually linked to a player who is using it. Is there something I’m not getting at here?

Nevermind, sorry, I am thinking server, I notice this may be all local, including the skateboard.

Because you’re using the Control module, you should have this script in StarterPlayerScripts if it isn’t already.

Using the moveSkate function provided by @DevLungZ, I have optimized this code to work best when placed in the StarterPlayerScripts folder, which is located under StarterPlayer:

local playersService = game:GetService("Players")
local userInputService = game:GetService("UserInputService")

local localPlayer = playersService.LocalPlayer
local playerModule = require(script.Parent:WaitForChild("PlayerModule"))
local controlModule = playerModule:GetControls()
controlModule:Disable()

local character, humanoid, rootpart
local rootPartChanged

local function loadCharacter()
	if typeof(rootPartChanged) == 'RBXScriptConnection' then
		rootPartChanged:Disconnect()
	end

	character = localPlayer.Character
	humanoid = character:WaitForChild('Humanoid')
	rootpart = humanoid.RootPart

	rootPartChanged = humanoid:GetPropertyChangedSignal('RootPart'):Connect(function()
		rootpart = humanoid.RootPart
	end)
end

pcall(loadCharacter)
localPlayer.CharacterAdded:Connect(loadCharacter)

local function weld(part0 : BasePart, part1 : BasePart)
	if (not part0:IsA("BasePart")) or (not part1:IsA("BasePart")) then --NOTE: I used brackets just because I don't know the operator priority
		error("Can't weld non BasePart objects")
	end

	local weld = Instance.new("Weld")

	weld.Part0 = part0
	weld.Part1 = part1

	weld.C0 = part0.CFrame:Inverse()
	weld.C1 = part1.CFrame:Inverse()

	weld.Parent = part0
	return weld
end

local function attachSkate(leftLeg, skateboardModel)
	character:MoveTo(rootpart.Position + Vector3.new(0, 3, 0))
	skateboardModel:MoveTo(leftLeg.Position - Vector3.new(0, leftLeg.Size.Y / 2, 0))
	weld(leftLeg, skateboardModel.Cube)
end

local function moveSkate()
	if typeof(character) == 'Instance' and character:IsA('Model') then
		local skateboardModel = workspace:FindFirstChild('Skateboard')
		local primaryPart = skateboardModel.PrimaryPart
		local leftLeg = character:FindFirstChild("LeftLeg") or character:FindFirstChild("LeftLowerLeg")

		if primaryPart and leftLeg then
			attachSkate(leftLeg, skateboardModel)
			local direction = leftLeg.CFrame.LookVector * -5
			primaryPart.AssemblyLinearVelocity = Vector3.new(direction.X, 0, direction.Z)
		end
	end
end


userInputService.InputBegan:Connect(function(inputObject)
	if inputObject.KeyCode.Name == 'W' then
		moveSkate()
	end
end)

Because of the nature of StarterPlayerScripts, it does not work the same way as StarterCharacterScripts and does require you to retrieve the character each time it spawns back in, so I have included that functionality, alongside retrieving the RootPart and the Humanoid.

1 Like

I mixed multiple solutions, some code from @DevLungZ , some code from @04nv and did some stuff myself. Here’s my code now:

local Players = game:GetService("Players")
local InputServ = game:GetService("UserInputService")
local plr = Players.LocalPlayer
local playerModule = require(plr.PlayerScripts:WaitForChild("PlayerModule"))
local controls = playerModule:GetControls()
rootPartChanged = nil
local skate = workspace.Skateboard

controls:Disable()

plr.CharacterAdded:Wait()


local function loadCharacter()
	if typeof(rootPartChanged) == "RBXScriptConnection" then
		rootPartChanged:Disconnect()
	end

	local character = plr.Character
	local humanoid = character:WaitForChild("Humanoid")
	local rootPart = humanoid.RootPart

	rootPartChanged = humanoid:GetPropertyChangedSignal("RootPart"):Connect(function()
		rootPart = humanoid.RootPart
	end)
	
	humanoid:ChangeState(Enum.HumanoidStateType.Physics)
end

pcall(loadCharacter)
plr.CharacterAdded:Connect(loadCharacter)

local function weld(part0 : BasePart, part1 : BasePart)
	if (not part0:IsA("BasePart")) or (not part1:IsA("BasePart")) then --NOTE: I used brackets just because I don't know the operator priority
		error("Can't weld non BasePart objects")
	end
	
	local weld = Instance.new("Weld")
	
	weld.Part0 = part0
	weld.Part1 = part1
	
	weld.C0 = part0.CFrame:Inverse()
	weld.C1 = part1.CFrame:Inverse()
	
	weld.Parent = part0
	return weld
end

local function attachSkate(plrChar : Model, skate : Model)
	local leftLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")
	print(leftLeg)
	
	plrChar:MoveTo(plrChar.HumanoidRootPart.Position + Vector3.new(0, 3, 0))
	skate:MoveTo(leftLeg.Position - Vector3.new(0, 1, 0))
	
	weld(leftLeg, skate.Cube)
end

local function moveSkate(plrChar)
	local root = workspace.Skateboard.PrimaryPart
	local leftLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")

	if leftLeg and not leftLeg:FindFirstChild("Weld") then
		attachSkate(plrChar, workspace.Skateboard)
	end
	-- Calculate the direction based on the left leg's orientation
	local direction = root.CFrame.LookVector * 25 -- Adjust the speed as needed

	-- Set the velocity of the skateboard's PrimaryPart
	root.AssemblyLinearVelocity = Vector3.new(direction.X, 0, direction.Z)
	
end

--[[local function moveSkate(plrChar : Model)
	local root = workspace.Skateboard.PrimaryPart
	root:ApplyImpulse((CFrame.new(root.AssemblyLinearVelocity) * CFrame.new(0, 0, -5 * workspace.Gravity)).Position)
	local leftLeg = plrChar:FindFirstChild("LeftLeg") or plrChar:FindFirstChild("LeftLowerLeg")
	if leftLeg and not leftLeg:FindFirstChild("Weld") then
		attachSkate(plrChar, workspace.Skateboard)
	end
end]]

InputServ.InputBegan:Connect(function(key)
	print(key.KeyCode.Name)
	local rad = math.rad
	if key.KeyCode.Name == "W" then
		moveSkate(plr.Character)
	elseif key.KeyCode.Name == "A" then
		skate:PivotTo(CFrame.new(workspace.Skateboard.PrimaryPart.Position) * CFrame.Angles(0, rad(30), 0))
	elseif key.KeyCode.Name == "D" then
		skate:PivotTo(CFrame.new(workspace.Skateboard.PrimaryPart.Position) * CFrame.Angles(0,rad(-30), 0))
	end
end)

My new issue is that I can’t rotate the skate and player correctly. Any ideas how to do this?

Try using AssemblyAngularVelocity.

1 Like

I haven’t thought of that. Thanks!

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