Hello, I am currently working on a heavily Monkey Ball inspired experience wherein the character travels through a stage while inside a physics ball and is unable to jump. I can implement this by welding the character to the part that is spawned at the same time as the player and turning off collision for the character, while manipulating it via increasing or decreasing rotational velocity while a key is held down.
Here are the scripts:
BallGive (Server side)
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 = Vector3.new(7, 7, 7.375);
Ball.Material = Enum.Material.Plastic;
Ball.CFrame = Player.Character.HumanoidRootPart.CFrame;
Ball.Transparency = 0.85;
Ball.Color = Color3.new(1, 0.32549, 0.337255);
Ball.CustomPhysicalProperties = PhysicalProperties.new(1, 2, 0.2, 1, 1)
end
GiveBall();
Player.CharacterAdded:Connect(function()
GiveBall();
end)
end)
BallMove (LocalScript)
local Player = game:GetService('Players').LocalPlayer;
local InputService = game:GetService('UserInputService');
local Camera = workspace.CurrentCamera;
local Settings = {
Speed = 50,
Size = Vector3.new(7, 7, 7.25)
}
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.Exclude;
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)
Thing is, I want the player character to eventually be upright and performing animations based on the velocity of the ball. I don’t know how to do that, since welding forces both position and rotation to match. I have tried to use ball&socket constraints to maintain position separate from orientation but I cannot get the character to spawn inside the ball.
My latest attempt is below:
LocalScript is identical. ServerScript is as follows:
game:GetService('Players').PlayerAdded:Connect(function(Player)
local GiveBall = function()
local Ball = Instance.new("Part");
Ball.Name = "Ball"
local BallSocket = Instance.new("BallSocketConstraint")
BallSocket.Name = "BallSocket"
local Character = Player.Character or Player.CharacterAdded:Wait();
local Humanoid = Character:WaitForChild('Humanoid');
Ball.Parent = Character;
Ball.Anchored = false;
Ball.Shape = Enum.PartType.Ball;
Ball.Size = Vector3.new(7, 7, 7.375);
Ball.Material = Enum.Material.Plastic;
Ball.CFrame = Player.Character.HumanoidRootPart.CFrame;
Ball.Transparency = 0.85;
Ball.Color = Color3.new(1, 0.32549, 0.337255);
Ball.CustomPhysicalProperties = PhysicalProperties.new(1, 2, 0.2, 1, 1)
Character.HumanoidRootPart.Position = Ball.CFrame.Position
BallSocket.Parent = Ball
BallSocket.Attachment0 = Ball
BallSocket.Attachment1 = Character.HumanoidRootPart
BallSocket.Attachment0.Position = Ball.CFrame.Position -- adjust if needed
BallSocket.Attachment1.Position = Ball.Player.Character.HumanoidRootPart.CFrame.Position -- adjust if needed
BallSocket.LimitsEnabled = false
BallSocket.MaxFrictionTorque = 0
end
GiveBall()
Player.CharacterAdded:Connect(function()
GiveBall()
end)
end)
Can I still theoretically do this with Ball and Socket? Should I try using weldconstraint or something else entirely?