How would I make this automatically seat the player?

I am looking to spawn the studio template gyro balls on game event and then to automatically seat the player into the ball. How would I go about doing that? I tried to edit the Occupant script to call the enterBall() module to seat the player and it works but the ball won’t move and the module script returns a no humanoid error when a humanoid is connected to it. However if the player leaves the ball and reenters, then it works fine but of course it defeats the purpose the automatically place the player. Not sure what to do here. Here is the original script for the gyro ball, and the Ball itself gets added to the player in workspace:

local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local enterBall = require(script.enterBall)
local exitBall = require(script.exitBall)
local abilities = require(script.ability)
local player = game.Players.LocalPlayer
local ball = script.Parent.Parent.Parent
local driverSeat = ball.DriverSeat
local enterPrompt = ball.EnterPrompt
local exitPrompt = ball.ExitPrompt
local abilityPrompt = ball.AbilityPrompt
local sounds = ball.DriverSeat.Sounds
local fx = ball.DriverSeat
local basepart = ball.Exterior.CollisionBall
local abilnumber = ball.DriverSeat.AbilityType
-- If Ball speed is less than this value and occupant exists, exit prompt will appear
local EXIT_PROMPT_SPEED_THRESHOLD = 1
local MIN_TIME_BEFORE_EXIT_PROMPT_SHOWN = 2
local exitPromptConnection

-- Get any "disable exiting ball" parts
local disableExitBallBoundsParts = CollectionService:GetTagged("DisableExitingBall")

-- Listen for conditions that change whether the exit prompt is enabled
local function trackExitPromptEnabled(): RBXScriptConnection
	local connection = RunService.Heartbeat:Connect(function()
		-- check if ball is in the disable exit prompt bounds
		local isBallInDisableExitPromptBounds = false
		for _, disableExitBallBoundsPart in disableExitBallBoundsParts do
			local partsInBounds =
				Workspace:GetPartBoundsInBox(disableExitBallBoundsPart:GetPivot(), disableExitBallBoundsPart.Size)
			for _, part in partsInBounds do
				if part:IsDescendantOf(ball) then
					isBallInDisableExitPromptBounds = true
					break
				end
			end
		end

		-- check if ball speed is slow enough to exit the ball
		local isBallSpeedLow = false
		local ballVelocity = ball.PrimaryPart.AssemblyLinearVelocity
		if ballVelocity.Magnitude < EXIT_PROMPT_SPEED_THRESHOLD then
			isBallSpeedLow = true
		end

		-- enable exit prompt if ball spped is slow enough and ball is not in the disable exit prompt bounds
		if isBallSpeedLow and not isBallInDisableExitPromptBounds then
			exitPrompt.Enabled = true
		else
			exitPrompt.Enabled = false
		end
	end)
	return connection
end

local function onOccupantChanged()
	local humanoid = driverSeat.Occupant
	enterPrompt.Enabled = humanoid == nil
	--Exit prompt will initially be false regardless of the occupancy state
	exitPrompt.Enabled = false

	if humanoid then
		-- Delay allows player to explore controlling the ball without immediately being prompted to exit
		task.delay(MIN_TIME_BEFORE_EXIT_PROMPT_SHOWN, function()
			exitPromptConnection = trackExitPromptEnabled()
		end)
	else
		if exitPromptConnection then
			exitPromptConnection:Disconnect()
			exitPromptConnection = nil
		end
	end
end


------The code I injected below-------------
basepart.Touched:Connect(function(other)
	if other.Name == "MysteryBox" and driverSeat.abilityget.Value == false then
		local humanoid = driverSeat.Occupant
		driverSeat.abilityget.Value = true
		sounds["Space Chimes"]:Play()
		fx.GeneralAbilities.Stars.Enabled = true
		task.wait(4)
		sounds["Enemy Gadget - Brawl Stars SFX"]:Play()
		driverSeat.abilityget.Value = true
		task.wait(1)
		fx.GeneralAbilities.Stars.Enabled = false
		local number = math.random(1,5)
		task.wait()
		abilnumber.Value = number
		if number == 1 then
			abilityPrompt.ObjectText = "You got: Overload Ability!"
		elseif number == 2 then
			abilityPrompt.ObjectText = "You got: Damage Ring Ability!"
		elseif number == 3 then
			abilityPrompt.ObjectText = "You got: Fire Ball Ability!"
		elseif number == 4 then
			abilityPrompt.ObjectText = "You got: Ice Cube Ability!"
		elseif number == 5 then
			abilityPrompt.ObjectText = "You got: SUPER Ability!"
		end
		abilityPrompt.Enabled = true
			
	
	end
end)

local function initialize()
	driverSeat:GetPropertyChangedSignal("Occupant"):Connect(onOccupantChanged)
	enterPrompt.Triggered:Connect(enterBall)
	exitPrompt.Triggered:Connect(exitBall)
	abilityPrompt.Triggered:Connect(abilities)
end

initialize()

And the module script:

local ball = script.Parent.Parent.Parent.Parent
local driverSeat = ball.DriverSeat

-- Logic for player entering the ball
local function enterBall(player: Player)
	local character = ball.Parent
	if not character then
		return
	end

	if driverSeat.Occupant then
		return
	end

	local humanoid = character:FindFirstChild("Humanoid")
	task.wait()
	assert(humanoid, "No humanoid found!")

	-- Force a character to sit in the ball
	driverSeat:Sit(humanoid)
	script.Parent.Parent.Parent.Parent.DriverSeat.Sounds.Engine.Script.Enabled = true
	script.Parent.Parent.Parent.Parent.DriverSeat.Sounds.Engine:Play()

	-- Disable collisions
	for _, part in character:GetDescendants() do
		if part:IsA("BasePart") then
			local noCollisionConstraint = Instance.new("NoCollisionConstraint")
			noCollisionConstraint.Part0 = ball.Exterior.CollisionBall
			noCollisionConstraint.Part1 = part
			noCollisionConstraint.Parent = ball.NoCollisionConstraints
		end
	end

	-- Update network owner of the ball
	ball.PrimaryPart:SetNetworkOwner(player)
end

return enterBall

And forgive my script.Parent.Parent.Parent nonsense, im just trying to get it to work first before I make it efficient

2 Likes

Set the Seat.Occupant property of the chair to the player’s character

1 Like

In the main script or the module script?

Either works, doesn’t really matter as long as it’s being called on the server

So i tried setting the module script to take the humanoid to the seat.occupant, but keep getting this error. I have near-zero knowledge of this level scripting so forgive me for not understanding what you mean by setting the property to the players character. I have no idea where to even look to insert that lol

local function enterBall(player: Player)
	local character = player.Character
	if not character then
		return
	end
	local humanoid = character:WaitForChild("Humanoid")
	driverSeat.Occupant = humanoid
	--assert(humanoid, "No humanoid found!")
	
	
	if driverSeat.Occupant then
		return
	end

I’m not good with seats either, but I believe they require the character instead of the humanoid

well originally the script already forces the player into the seat when enterBall() is called but the ball is locked in place for some reason. Im not claiming to say that the seat occupant is not the issue but the seat occupant value does turn to the humanoid when it gets placed in.

Is the player being defined correctly?

I read into it, the seat occupant property is read only, use :Sit()

:sit() is being called in the occupant script. Im looking more into the other script functions to see if something is blocking it

Seat.Occupant is read only, so you can’t set it as others have suggested.

Since Sit.Humanoid isn’t working it may be that a local or server script can’t call this.

Also, are you sure you’re collecting the workspace Humanoid or the Players service Humanoid?

I havent any idea lol. I am still very new to scripting but I am about to decide against automatically seating the players if I cannot figure it out. Id rather have them enter it manually lol