ContextActionService Vs UserInputService? (And other questions)

Currently, I’m trying to create a marble movers type of game, and being the fairly inexperienced coder as I am, I’m looking for some aid with a couple of questions.

I am trying to achieve a fluid movement using Body Force, however , whenever I use a key, it is far from fluid.

(For reference, this is what I’m aiming for)

A couple questions that I have:

~For regular movement, how would you continuously check if the player is holding down a key (W,A,S,D)? Would I just have to loop the function?
(ANSWERED)

  • Use while UserInputService:IsKeyDown(inputObject.KeyCode) == true do to simulate the player holding the button.

~Would ContextActionService or UserInputService be better for this situation?

~Can other players visibly see another user’s ball rolling if the body force is adjusted via local script?
(ANSWERED)

  • Yes, other players can see movement.

Currently, in a server script, this is the code to spawn in the player as a marble:

Code
game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(Char)
		local Weld = Instance.new("WeldConstraint")
		
		local Marble = Instance.new("Part")
		Weld.Parent = Marble
		local BodyForce = Instance.new("BodyForce",Marble)
		BodyForce.Force = Vector3.new(0,1,0)
		Marble.Shape = "Ball"
		Marble.Material = "SmoothPlastic"
		Marble.Transparency = .5
		
		Marble.Position = Vector3.new(10,10,10)
		Marble.Size = Vector3.new(7,7,7)
		Marble.Anchored = false
		Marble.Massless = true
		Marble.Name = "Marble"
		
		Char.Archivable = true
		
		Marble.Parent = Char
		Char:WaitForChild("HumanoidRootPart").CFrame = CFrame.new(Marble.Position)
		
		Char.Humanoid.PlatformStand = true
		for i,v in pairs(Char:GetChildren()) do
			if v:IsA("BasePart") then v.Massless = true
				
			end
		end
		
		Weld.Part0 = Char.HumanoidRootPart
		Weld.Part1 = Marble
	end)
end)

Due to troubles with studio, I lost my progress for changing the body force’s velocity, but using a repeat loop and contextactionservice, i managed to create this

but as you may have noticed, its far from perfect since when I hold W to go forward, it gains more and more momentum that I cant turn to go a different way, and when I release the key, it continues to roll in the direction held even though i tween its force to 0.

Any help would be great help! thank you!

EDIT: I’ve been trying out some stuff, and here is what I have in a local script:

Code #2
wait()
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")

local Player = game.Players.LocalPlayer
local Character = game.Workspace:WaitForChild(Player.Name)
local CurrentCamera = game.Workspace.CurrentCamera

local Marble = Character:WaitForChild("Marble")
local MarbleBodyForce = Marble.BodyForce

local function MoveBall (actionName, inputState, inputObject)
	if inputState == Enum.UserInputState.Begin then
		if inputObject.KeyCode == Enum.KeyCode.W then
			while UserInputService:IsKeyDown(inputObject.KeyCode) == true  do
				wait()
				print(":)")
				MarbleBodyForce.Force = MarbleBodyForce.Force + (CurrentCamera.CFrame.LookVector * Vector3.new(5,0,5))
				
			end
			MarbleBodyForce.Force = Vector3.new(0,0,0)
		end

	end
end
	
ContextActionService:BindAction("Ball", MoveBall, true, Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.S,Enum.KeyCode.D)

But i’ve encountered the same issue, for when the ball’s force is 0 it keeps on rolling.

1 Like

Possible fix: Instead of setting the force to 0 right away, set it to a negative number (or positive if its already negative) and then wait(5) or so and then set it to 0 cause with roblox physics, it’ll just keep rolling

I tried something like that, but its really hard to calculate have much negative force you’re going to need to stop the momentum.

I have resorted to using body position and its worked pretty good, but doesnt retain some of the physics that I like with body force

I use

Marble.BodyPosition.Position = Marble.BodyPosition.Position + CurrentCamera.CFrame.LookVector * Vector3.new(2,0,2)

to move around via position, but as the body mover suggests, it likes to stay at that position

it can be tested here:

You should set ball’s network ownership to Player then it will replicate to other people.

One alternate solution is to apply a body gyro to the marble with low enough torque to simulate friction and prevent the ball from moving.

I havent worked with body gyro, i can surely give that a try C:

I just now tested it with a friend and they can see the changes in the balls movement even the the force is applied on the client

Additional problem with body force - If you turn your screen , the force in the direction you were looking at before is much stronger than where you are now looking thus you keep rolling in that direction >.<