Загрузка данных


-- StuntClient
-- place in StarterPlayer > StarterPlayerScripts

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local trickEvent = ReplicatedStorage:WaitForChild("ScooterTrick")

-- replace these placeholders with your published animation IDs
local AnimationIds = {
	Ride = "rbxassetid://0",
	Jump = "rbxassetid://0",
	Barspin = "rbxassetid://0",
	Tailwhip = "rbxassetid://0",
	Backflip = "rbxassetid://0",
	Frontflip = "rbxassetid://0",
	Wheelie = "rbxassetid://0",
	Fall = "rbxassetid://0",
}

local character
local humanoid
local animator
local tracks = {}

local riding = false
local wheelie = false
local busy = false
local lastJump = 0

local function stopTrack(name, fade)
	local track = tracks[name]
	if track and track.IsPlaying then
		track:Stop(fade or 0.15)
	end
end

local function playTrack(name, looped)
	local id = AnimationIds[name]

	if not id or id == "rbxassetid://0" then
		warn("Add an animation ID for: " .. name)
		return nil
	end

	if tracks[name] then
		tracks[name].Looped = looped or false
		tracks[name]:Play(0.15)
		return tracks[name]
	end

	local animation = Instance.new("Animation")
	animation.Name = name
	animation.AnimationId = id

	local success, result = pcall(function()
		return animator:LoadAnimation(animation)
	end)

	animation:Destroy()

	if not success then
		warn("Could not load animation:", name, result)
		return nil
	end

	tracks[name] = result
	tracks[name].Looped = looped or false
	tracks[name].Priority = Enum.AnimationPriority.Action
	tracks[name]:Play(0.15)

	return tracks[name]
end

local function stopAll()
	for name in pairs(tracks) do
		stopTrack(name, 0.15)
	end
end

local function setupCharacter(char)
	stopAll()

	character = char
	humanoid = char:WaitForChild("Humanoid")
	animator = humanoid:WaitForChild("Animator")

	riding = false
	wheelie = false
	busy = false
end

local function isOnScooter()
	if not humanoid then
		return false
	end

	local seat = humanoid.SeatPart
	return seat ~= nil
		and seat:IsA("VehicleSeat")
		and seat:GetAttribute("IsScooter") == true
end

local function refreshRideState()
	local shouldRide = isOnScooter()

	if shouldRide == riding then
		return
	end

	riding = shouldRide
	wheelie = false

	if riding then
		playTrack("Ride", true)
	else
		stopAll()
	end
end

local function doTrick(name)
	if not riding or busy or not isOnScooter() then
		return
	end

	busy = true
	wheelie = false

	stopTrack("Wheelie")

	if name == "Barspin" or name == "Tailwhip"
		or name == "Backflip" or name == "Frontflip" then

		playTrack(name, false)
		trickEvent:FireServer(name)

		task.delay(1.1, function()
			busy = false

			if riding and isOnScooter() then
				playTrack("Ride", true)
			end
		end)
	end
end

local function doJump()
	if not riding or not isOnScooter() then
		return
	end

	if os.clock() - lastJump < 0.4 then
		return
	end

	lastJump = os.clock()

	playTrack("Jump", false)
end

local function toggleWheelie()
	if not riding or not isOnScooter() or busy then
		return
	end

	wheelie = not wheelie

	if wheelie then
		stopTrack("Ride")
		playTrack("Wheelie", true)
	else
		stopTrack("Wheelie")
		playTrack("Ride", true)
	end
end

UserInputService.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end

	if input.KeyCode == Enum.KeyCode.C then
		if riding and humanoid then
			humanoid.Sit = false
			wheelie = false
			stopAll()
		end

	elseif input.KeyCode == Enum.KeyCode.Space then
		doJump()

	elseif input.KeyCode == Enum.KeyCode.Q then
		doTrick("Barspin")

	elseif input.KeyCode == Enum.KeyCode.E then
		doTrick("Tailwhip")

	elseif input.KeyCode == Enum.KeyCode.R then
		doTrick("Backflip")

	elseif input.KeyCode == Enum.KeyCode.T then
		doTrick("Frontflip")

	elseif input.KeyCode == Enum.KeyCode.V then
		toggleWheelie()
	end
end)

trickEvent.OnClientEvent:Connect(function(result, trickName)
	if result == "Bail" then
		busy = true
		stopAll()
		playTrack("Fall", false)

		task.delay(1.2, function()
			busy = false
		end)

	elseif result == "Success" then
		-- The trick animation was already started locally.
		-- Scooter-part rotation should be handled separately.
	end
end)

local function monitorCharacter(char)
	setupCharacter(char)

	humanoid:GetPropertyChangedSignal("SeatPart"):Connect(function()
		refreshRideState()
	end)

	refreshRideState()
end

if player.Character then
	monitorCharacter(player.Character)
end

player.CharacterAdded:Connect(monitorCharacter)