I’ve done it! Or at least done something!
It’s not what I originally set out to do (this moves the character relative to the direction they are facing, instead of the direction the player is facing), but I don’t feel like learning trigonometry right now and I think I prefer this system more (I like to be able to look around while my character is moving)
robloxapp-20211106-1655063.wmv (1.2 MB) (it’s not actually jumpy/movement is gradual, Im not sure what happened to the video recording to make it look like its jumping)
Here’s my code - This script is a LocalScript named “ControlScript” played in StarterPlayerScripts
--[[
The existence of the ControlScript causes Roblox's default control scripts/modules to not load.
]]
---------------------------------------------------------------------------------------------------------------------------------------------
-- VARIABLES
---------------------------------------------------------------------------------------------------------------------------------------------
-- SERVICES
local ContextActionService = game:GetService("ContextActionService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
-- PLAYER VARS
local Player = game.Players.LocalPlayer
local PlayerCamera = workspace.CurrentCamera
if not Player.Character then Player.CharacterAdded:Wait() end
local HumanoidRootPart = Player.Character:WaitForChild("HumanoidRootPart")
-- MOTION VARS
local CharVelocity = HumanoidRootPart:WaitForChild("BodyVelocity")
local CharRotation = HumanoidRootPart:WaitForChild("BodyAngularVelocity")
local Xdirection
local Zdirection
local rotation
-- PLAYER CONTROL VARS
local FORWARD_KEY = Enum.KeyCode.W
local LEFT_KEY = Enum.KeyCode.A
local RIGHT_KEY = Enum.KeyCode.D
local RotationSpeed = 3 -- The angle the character turns per rotation. A higher value causes them to turn faster
local CharSpeed = 10 -- The speed at which the character moves forward
---------------------------------------------------------------------------------------------------------------------------------------------
-- FUNCTIONS
---------------------------------------------------------------------------------------------------------------------------------------------
-- APPLY FORWARD VELOCITY
-- Applies velocity to the character to move them forward
local function applyForwardVelocity()
-- Get the direction they are facing
rotation = HumanoidRootPart.Orientation.Y/10
Xdirection = math.sin(0.174532925*rotation)*(CharSpeed * -1)
Zdirection = math.cos(0.174532925*rotation)*(CharSpeed * -1)
-- Apply velocity
CharVelocity.Velocity = Vector3.new(Xdirection, 0, Zdirection)
end
-- FORWARD
-- The player has pressed the Forward key
local function forward(actionName, inputState)
-- inputState will be Enum.UserInputState.Begin if the player has Pressed the key
-- it will be Enum.UserInputState.End when the player Releases the key
if inputState == Enum.UserInputState.Begin then
-- Continue movement while W key is held
-- For as long as the W key is held, continue adjusting the force being applied (as the character may be turning left or right)
while UserInputService:IsKeyDown(FORWARD_KEY) do
-- Move
applyForwardVelocity()
wait(0.1)
end
-- The player has released the Forward key
elseif inputState == Enum.UserInputState.End then
-- Stop moving the character
CharVelocity.Velocity = Vector3.new(0, 0, 0)
end
end
-- LEFT
-- The player has pressed the Left key
local function left(actionName, inputState)
-- Key Down
if inputState == Enum.UserInputState.Begin then
-- Initiate turn
CharRotation.AngularVelocity = Vector3.new(0, RotationSpeed, 0)
-- While they are holding the Left key
while UserInputService:IsKeyDown(LEFT_KEY) do
-- If they are not holding the forward key...
if not UserInputService:IsKeyDown(FORWARD_KEY) then
-- Move them forward (character can only rotate while moving)
applyForwardVelocity()
end
wait(0.1)
end
-- Key Up
elseif inputState == Enum.UserInputState.End then
-- If they are not holding the forward key, stop movement
if not UserInputService:IsKeyDown(FORWARD_KEY) then
CharVelocity.Velocity = Vector3.new(0, 0, 0)
end
if UserInputService:IsKeyDown(RIGHT_KEY) then
CharRotation.AngularVelocity = Vector3.new(0, RotationSpeed * -1, 0)
else
CharRotation.AngularVelocity = Vector3.new(0, 0, 0)
end
end
end
-- RIGHT
-- The player has pressed the Right key
local function right(actionName, inputState)
-- Key Down
if inputState == Enum.UserInputState.Begin then
-- Initiate turn
CharRotation.AngularVelocity = Vector3.new(0, RotationSpeed * -1, 0)
-- While they are holding the key
while UserInputService:IsKeyDown(RIGHT_KEY) do
-- If they are not holding the forward key...
if not UserInputService:IsKeyDown(FORWARD_KEY) then
-- Move them forward (character can only rotate while moving)
applyForwardVelocity()
end
wait(0.1)
end
-- Key Up
elseif inputState == Enum.UserInputState.End then
-- If they are not holding the forward key, stop movement
if not UserInputService:IsKeyDown(FORWARD_KEY) then
CharVelocity.Velocity = Vector3.new(0, 0, 0)
end
if UserInputService:IsKeyDown(LEFT_KEY) then
CharRotation.AngularVelocity = Vector3.new(0, RotationSpeed, 0)
else
CharRotation.AngularVelocity = Vector3.new(0, 0, 0)
end
end
end
-- BINDINGS
ContextActionService:BindAction("Forward", forward, false, FORWARD_KEY)
ContextActionService:BindAction("Left", left, false, LEFT_KEY)
ContextActionService:BindAction("Right", right, false, RIGHT_KEY)
Also
- A BodyVelocity (named “BodyVelocity”) must be parented to the player’s HumanoidRootPart
I set the MaxForce X and Z values very high so that the character can have adjustable speeds. The Y of the MaxForce has to be 0 so that gravity is still applied to the character.
- A BodyAngularVelocity (named “BodyAngularVelocity”) must also be parented to the player’s HumanoidRootPart. you don’t really have to change any values there (but change the starting velocity to 0 0 0)
I used this thread to move the character forward the direction they are facing: How can I make a character move to the direction it is facing?
It’s definitely not perfect and I have to mess with it more (making it modular so that different devices can use it) and the frequency (making it Wait(0.1)) is probably not perfect but it works
feedback appreciated because im still suspicious of loops that use wait()