How do I add a player turn radius?

I am making a creature survival game where players need to turn slowly and should not be able to turn instantly but nothing I can find is useful. I don’t need a whole tutorial, just like… where do I even start? What even affects player movement? Everything I can find mentions outdated scripts that don’t exist.

  • When the player is holding W and looking a different direction than the character, I want the character to walk forward while slowly turning to face the same direction as the camera
  • When the player is holding A, D, S, AW or DW, I want them to walk forward while slowly rotating to face that direction relative to the camera

Basically the same control system as Creatures of Sonaria.

There isn’t really any system/property in place to handle this. I was able to find this post:

Thank you, I saw that before but that didn’t work. I know there’s no easy system in place and I’m going to have to code an entire movement system from the ground up, I just have no idea what script handles player input to begin with and have been unable to find it.

There is not script that handles built-in character “Humanoid” physics, which is pretty different from the physics of everything else. E.g. you can’t change how collisions or jumping works with Humanoid characters. You can change how it’s controlled though, since this is all handled by a LocalScript in called “ControlScript”. If you make another script with the same name and put it in StarterPlayerScripts, the built in ControlScript will be overwritten and you can make your own controls from scratch. If you want to modify the built in one, you can test the game, then open Player1.PlayerScripts to copy the default one.

There’s also a CameraScript that controls the camera. Changing the ControlScript might break the CameraScript, or just cause it to throw some yellow warnings. As long as it works, it’s probably safe to ignore them.

1 Like

Thank you,
I’m confused because I can’t find ControlScript. There’s ControlModule but no ControlScript.
image

1 Like

I think I’ve found out how I can replace default controls using my own ControlScript (with help from this thread). I don’t understand any of this. Wish me luck!

1 Like

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()

2 Likes

I’m sorry I only noticed your post now. But if you are still using that method, I’d recommend to not to divide the Orientation.Y by 10, but instead just add 0 to the sin and cos factors: 0.0174532925 (It is the same as 0.174532925/10)

local function applyForwardVelocity()
	-- Get the direction they are facing
	rotation = HumanoidRootPart.Orientation.Y
	Xdirection = math.sin(0.0174532925*rotation)*(CharSpeed * -1)
	Zdirection = math.cos(0.0174532925*rotation)*(CharSpeed * -1)
	-- Apply velocity
	CharVelocity.Velocity = Vector3.new(Xdirection, 0, Zdirection)	
end

Just realised afterwards that it was just slowing down the code. Though if you have found a better way, I’d be happy if you shared it.