Some of the Roblox Studio education is within their pre-loaded project called Galatic Speedway.
I wanted to give the speeder physics a try but it looks like there is now a bug that doesn’t allow the player to fly with the default tester speeder (or any speeder you build, for that matter).
It now gives an error when you try to spawn/fly the speeder:
Player:Move called, but player currently has no humanoid.
I am wondering if the script is converting or despawning the player after it turns the player into a speeder? And this is causing the error? I had no idea.
I believe the problem is in ReplicatedStorage > ModuleScripts > PlayerConverter but I am not 100% certain. If you want you can fire up Studio and check it out.
If anyone can figure out the solution and post it here, maybe the Roblox team can patch and we can get this resource working for new players like myself again!
PlayerConverter script shown below.
-- ================================================================================
-- ================================================================================
-- PlayerConverter
-- ================================================================================
-- ================================================================================
local PlayerConverter = {}
-- ================================================================================
-- VARIABLES
-- ================================================================================
-- Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local PhysicsService = game:GetService("PhysicsService")
local ContextActionService = game:GetService("ContextActionService")
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
-- Device check
local IS_CONSOLE = GuiService:IsTenFootInterface()
local IS_MOBILE = UserInputService.TouchEnabled and not UserInputService.MouseEnabled and not IS_CONSOLE
-- SpeederScripts
local SpeederScripts = ReplicatedStorage:FindFirstChild("SpeederScripts")
local Controller = SpeederScripts:FindFirstChild("Controller")
-- Events
local Events = ReplicatedStorage:FindFirstChild("Events")
local LoadSpeeder = Events:FindFirstChild("LoadSpeeder")
local LoadCharacter = Events:FindFirstChild("LoadCharacter")
local RemoveActivePlayer = Events:FindFirstChild("RemoveActivePlayer")
local CheckpointEvent = Events:FindFirstChild("CheckpointEvent")
-- Sounds
local Soundscape = game.Soundscape
local ExitSound = Soundscape:FindFirstChild("ExitSound")
-- SpeederSpawnLocation part
local SpeederSpawnLocation = workspace:FindFirstChild("SpeederSpawnLocation")
-- Static variables
local _SPEEDEROBJECTSCOLLISIONGROUP = "SpeederObjects"
-- ================================================================================
-- ================================================================================
-- LOCAL FUNCTIONS
-- ================================================================================
local function setModelAnchored(parent, anchored)
for _, child in ipairs(parent:GetChildren()) do
if (child:IsA("BasePart")) or (child:IsA("MeshPart")) then
child.Anchored = anchored
end
setModelAnchored(child, anchored)
end
end -- setModelAnchored()
local function setModelCanCollide(parent, canCollide)
for _, child in ipairs(parent:GetChildren()) do
if (child:IsA("BasePart")) or (child:IsA("MeshPart")) then
child.CanCollide = canCollide
end
setModelAnchored(child, canCollide)
end
end -- setModelCanCollide()
local function setModelTransparency(parent, transparency)
for _, child in ipairs(parent:GetChildren()) do
if (child:IsA("BasePart")) or (child:IsA("MeshPart")) then
child.Transparency = transparency
end
setModelTransparency(child, transparency)
end
end -- setModelTransparency()
local function removeLimbsAndThings(character)
for _, child in ipairs(character:GetChildren()) do
removeLimbsAndThings(child)
if (not child:IsA("Humanoid")) and (not child:IsA("Motor6D"))
and (child.Name ~= "Head") and (child.Name ~= "UpperTorso") then
child:Destroy()
end
end
end -- removeLimbsAndThings()
local function insertModelIntoCharacter(character, model)
for _, child in ipairs(model:GetChildren()) do
child.Parent = character
insertModelIntoCharacter(child, child)
end
end -- insertModelIntoCharacter()
local function setCollisionGroup(parent, group)
for _,part in pairs(parent:GetChildren()) do
if (part:IsA("BasePart") or (part:IsA("MeshPart"))) then
PhysicsService:SetPartCollisionGroup(part, group)
end
end
end -- SetCollisionGroup()
-- ================================================================================
-- ================================================================================
-- PUBLIC FUNCTIONS
-- ================================================================================
function PlayerConverter:PlayerToSpeeder(selection, racing)
if racing == nil then racing = false end
-- Fire RemoteEvent to handle conversion server-side
LoadSpeeder:FireServer(selection, racing)
end -- PlayerConverter:PlayerToSpeeder()
function PlayerConverter:PlayerToSpeederClient(racing)
if racing == nil then racing = false end
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local PlayerGui = player:FindFirstChild("PlayerGui")
-- Get player's character
local character = player.Character or player.CharacterAdded():wait()
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local head = character:FindFirstChild("Head")
-- Move HumanoidRotPart out of range of interaction NPC
if humanoidRootPart then
humanoidRootPart.Position = humanoidRootPart.Position + Vector3.new(0, 40, 0)
print("Move HumanoidRotPart out of range of interaction NPC")
end
if head then
head.Position = head.Position + Vector3.new(0, 40, 0)
end
-- Lock/Center and hide mouse
UserInputService.MouseIconEnabled = false
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputService.MouseIconEnabled = false
-- Disable touch control GUIs on mobile devices
if IS_MOBILE then
local TouchGui = PlayerGui:WaitForChild("TouchGui")
TouchGui.Enabled = false
end
if racing then
local countdownGui = PlayerGui:WaitForChild("CountdownGui")
countdownGui.TimerFrame.Visible = false
end
end -- PlayerConverter:PlayerToSpeederClient()
function PlayerConverter:PlayerToSpeederServer(player, selection, racing)
if racing == nil then racing = false end
-- Get player's character
local character = player.Character or player.CharacterAdded:wait()
-- Anchor and make limbs transparent
setModelAnchored(character, true)
setModelCanCollide(character, false)
setModelTransparency(character, 1)
-- Remove limbs and unecessay character parts
removeLimbsAndThings(character)
-- Clone selected speeder
local speeder = selection:clone()
print ("Speeder cloned")
-- Set character's PrimaryPart to speeder's PrimaryPart
local body = speeder:FindFirstChild("Body")
assert(body, "All speeders must have a part named Body. It will be used as the PrimaryPart")
speeder.PrimaryPart = body
character.PrimaryPart = body
character.PrimaryPart.Name = "HumanoidRootPart"
-- Set collision group so that players cannot collide when they are speeders
setCollisionGroup(speeder, _SPEEDEROBJECTSCOLLISIONGROUP)
-- Unanchor speeder
setModelAnchored(speeder, false)
-- Insert speeder model into character
insertModelIntoCharacter(character,speeder)
-- Clone speeder scripts into player
local controller = Controller:clone()
controller.Parent = character
-- Move player to SpeederSpawnLocation
character:SetPrimaryPartCFrame(SpeederSpawnLocation.CFrame)
LoadSpeeder:FireClient(player, racing)
end -- PlayerConverter:PlayerToSpeederServer()
-- Must be called client-side
function PlayerConverter:SpeederToPlayer(playSound)
-- LoadCharacter has to be fired server-side, so fire a RemoteEvent
-- to get it there
LoadCharacter:FireServer()
PlayerConverter:SpeederToPlayerClient(playSound)
end -- PlayerConverter:SpeederToPlayer()
function PlayerConverter:SpeederToPlayerServer(player)
player:LoadCharacter()
LoadCharacter:FireClient(player)
end -- PlayerConverter:SpeederToPlayer()
function PlayerConverter:SpeederToPlayerClient(playSound)
if playSound == nil then playSound = true end
-- Play sounds
if playSound and (UserInputService.MouseBehavior ~= Enum.MouseBehavior.Default) then
ExitSound:Play()
end
-- Unlock and show mouse
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
UserInputService.MouseIconEnabled = true
-- Remove user from race ActivePlayer's list (if racing)
RemoveActivePlayer:FireServer()
-- Enable touch control GUIs on mobile devices
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local PlayerGui = player:FindFirstChild("PlayerGui")
if IS_MOBILE then
local TouchGui = PlayerGui:WaitForChild("TouchGui")
TouchGui.Enabled = true
end
local TopBar = PlayerGui:WaitForChild("TopBar")
TopBar.Enabled = false
end -- PlayerConverter:SpeederToPlayerClient()
function PlayerConverter:UnlockPlayerControls()
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
UserInputService.MouseIconEnabled = true
-- Remove user from race ActivePlayer's list (if racing)
RemoveActivePlayer:FireServer()
-- Enable touch control GUIs on mobile devices
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local PlayerGui = player:FindFirstChild("PlayerGui")
if (IS_MOBILE) then
local TouchGui = PlayerGui:WaitForChild("TouchGui")
TouchGui.Enabled = true
end
local TopBar = PlayerGui:WaitForChild("TopBar")
TopBar.Enabled = false
end -- PlayerConverter:UnlockPlayerControls()
-- ================================================================================
return PlayerConverter