How to get character to spawn in a rolling ball?

I am trying to get players to spawn as a ball with their avatar in them similar to the game called: Super Blocky Ball

I got the player to spawn with the ball, but the ball doesn’t roll.

I’ve tried Humanoid:ChangeState(Enum.HumanoidStateType.Physics) & HumanoidRootPart.AssemblyLinearVelocity, but that hasn’t got the ball to roll.

What my script looks like in-game:

What I want:

Current Code (Server Script in ServerScriptService):

local OriginalBall = game.ServerStorage.Ball
local SpeedMultiplier = 50
game:GetService("PhysicsService"):RegisterCollisionGroup("Character")

game.Players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		HumanoidRootPart.CanCollide = false
		
		local BallClone = OriginalBall:Clone()
		BallClone.Parent = HumanoidRootPart
		BallClone.CFrame = HumanoidRootPart.CFrame
		BallClone.CanCollide = true
		
		local WeldConstraint = Instance.new("WeldConstraint", Character:WaitForChild("HumanoidRootPart"))
		WeldConstraint.Parent = Character:WaitForChild("HumanoidRootPart")
		WeldConstraint.Part0 = Character:WaitForChild("HumanoidRootPart")
		WeldConstraint.Part1 = BallClone
		
		for _, BasePart in ipairs(Character:GetChildren()) do
			if BasePart:IsA("BasePart") then
				BasePart.CollisionGroup = "Character"
			end
		end
		local Humanoid = Character:WaitForChild("Humanoid")
		while task.wait() do
			Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
			BallClone.AssemblyLinearVelocity = Vector3.new(Humanoid.MoveDirection.X * SpeedMultiplier, Humanoid.MoveDirection.Y, Humanoid.MoveDirection.Z * SpeedMultiplier)
			HumanoidRootPart.AssemblyLinearVelocity = Vector3.new(Humanoid.MoveDirection.X * SpeedMultiplier, Humanoid.MoveDirection.Y, Humanoid.MoveDirection.Z * SpeedMultiplier)
		end
	end)
end)
1 Like

Make sure you set the network ownership of the ball to the player, make the character PlatformStanding, and control the movement of the ball on the client.
What you could do is detect when they keys WASD are pressed, then apply some force to your BodyVelocity or whatever you plan to use. You can use the camera’s LookVector to tell which way you should be going.

How do I make it work for mobile then?

Server Script:

game:GetService('Players').PlayerAdded:Connect(function(Player)
	local GiveBall = function()
		local Ball = Instance.new("Part");
		Ball.Name = "Ball"
		local Weld = Instance.new("Weld");
		Weld.Name = "Giver"
		local Character = Player.Character or Player.CharacterAdded:Wait();
		local Humanoid = Character:WaitForChild('Humanoid');

		Weld.Parent = Ball;
		Weld.Part1 = Ball;
		Weld.Part0 = Character.HumanoidRootPart;

		Ball.Parent = Character;
		Ball.Anchored = false;
		Ball.Shape = Enum.PartType.Ball;
		Ball.Size = Player.Character.HumanoidRootPart.Size + Vector3.new(5, 5, 5);
		Ball.Material = Enum.Material.ForceField;
		Ball.CFrame = Player.Character.HumanoidRootPart.CFrame;
		Ball.Color = Color3.new(0, 0, 1);
	end

	GiveBall();

	Player.CharacterAdded:Connect(function()
		GiveBall();
	end)
end)

Local Script:

local Player = game:GetService('Players').LocalPlayer;
local InputService = game:GetService('UserInputService');
local Camera = workspace.CurrentCamera;
local Settings = {
	Speed = 30,
	JumpPower = 60,
	Size = Vector3.new(5, 5, 5)
}

local Character = Player.Character or Player.CharacterAdded:Wait();
local Humanoid = Character:WaitForChild('Humanoid');
local RayParams = RaycastParams.new();
local Ball = Character:WaitForChild('Ball');
local Connection;

Camera.CameraSubject = Ball
RayParams.FilterType = Enum.RaycastFilterType.Blacklist;
RayParams.FilterDescendantsInstances = {Character};

for _, v in next, Player.Character:GetChildren() do
	if v:IsA('BasePart') and v ~= Ball then
		v.Massless = true;
		v.CanCollide = false;
	end
end

Humanoid.Died:Connect(function() Connection:Disconnect() end);
Connection = game:GetService('RunService').RenderStepped:Connect(function(delta)
	Humanoid.PlatformStand = true;
	Ball.CanCollide = true;

	if InputService:IsKeyDown('W') then
		Ball.RotVelocity -= Camera.CFrame.RightVector * delta * Settings.Speed
	end

	if InputService:IsKeyDown('A') then
		Ball.RotVelocity -= Camera.CFrame.LookVector * delta * Settings.Speed
	end

	if InputService:IsKeyDown('S') then
		Ball.RotVelocity += Camera.CFrame.RightVector * delta * Settings.Speed
	end

	if InputService:IsKeyDown('D') then
		Ball.RotVelocity += Camera.CFrame.LookVector * delta * Settings.Speed
	end
end)

InputService.JumpRequest:Connect(function()
	if workspace:Raycast(Ball.Position, Vector3.new(0, -((Ball.Size.Y / 2) + 0.3), 0), RayParams) then
		Ball.Velocity = Ball.Velocity + Vector3.new(0, Settings.JumpPower, 0)
	end
end)
1 Like

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