What do you want to achieve? Keep it simple and clear!
i need to limit turning control when the player is charging by setting a limit
What is the issue? Include screenshots / videos if possible!
my rotations simply are not applying, the clamping is working.
What solutions have you tried so far? Did you look for solutions on the Creator Hub?
i have already looked on the creator hub but this is a more specific use case
im not the best at vector maths so it could be something really stupid
Relevant client code
local previousY = rootPart.Rotation.Y
game:GetService("RunService").RenderStepped:Connect(function()
if not chargingValue.Value then return end
local newY = rootPart.Rotation.Y
local diff = newY - previousY
diff = math.clamp(diff, -maxTurnRate, maxTurnRate)
local newRotation = CFrame.new(player.Character:GetPivot().Position) * CFrame.Angles(0, previousY + diff, 0)
player.Character:PivotTo(newRotation)
previousY = newY
end)
I am not sure exactly what you are trying to do, but this works
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local rootPart = character.HumanoidRootPart
local previousY = rootPart.Rotation.Y
local maxTurnRate = 50
local function rotateFun()
local newY = rootPart.Rotation.Y
local diff = newY - previousY
diff = math.clamp(diff, -maxTurnRate, maxTurnRate)
local newRotation = CFrame.new(player.Character:GetPivot().Position) * CFrame.Angles(0, previousY + diff, 0)
player.Character:PivotTo(newRotation)
previousY = newY
end
while true do
rotateFun()
task.wait(1)
end
Are you using another script, what script makes the player charge ? Its kinda hard to give a complete answer to your scenario/setup without seeing the full picture. How is the chargingValue.Value incrementing?
I just showed you a function being used inside a while true loop and how it works b/c I slowed it down. Something else may need to change, are you using other scripts ?
-- modules and services
local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local MovementFunctions = require(script.Parent:WaitForChild("MovementFunctions"))
local FREEZE_ACTION = "freezeMovement"
-- values
local chargingValue = script.Parent.Charging
local canChargeValue = script.Parent.CanCharge
local chargeDurationValue = script.Parent.ChargeDuration
-- constants
local baseMoveSpeed = 16
local maxTurnRate = script.Parent.MaxTurnRate.Value
-- player data
local player = Players.LocalPlayer
local mouse = player:GetMouse()
local humanoid: Humanoid = Players.LocalPlayer.Character:FindFirstChild("Humanoid")
local camera = workspace.CurrentCamera
local rootPart: BasePart = Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart")
local previousY = rootPart.Rotation.Y
local function rotateFun()
local newY = rootPart.Rotation.Y
local diff = newY - previousY
diff = math.clamp(diff, -maxTurnRate, maxTurnRate)
local newRotation = CFrame.new(player.Character:GetPivot().Position) * CFrame.Angles(0, previousY + diff, 0)
player.Character:PivotTo(newRotation)
previousY = newY
end
-- the following function initiates charging
mouse.Button2Down:Connect(function()
if chargingValue.Value or not canChargeValue.Value then
print("charge ended early due to missing requirements")
return
end
print("charging")
script.Parent.ChargeLeft.Value = chargeDurationValue.Value
chargingValue.Value = true
MovementFunctions.DisableMovement()
humanoid.WalkSpeed = script.Parent.ChargeSpeed.Value
for i=1, chargeDurationValue.Value / 0.05 do
MovementFunctions.ForceMovement()
print("chargingLoop")
rotateFun()
task.wait(0.05)
end
humanoid.WalkSpeed = baseMoveSpeed
MovementFunctions.EnableMovement()
chargingValue.Value = false
print("chargeEnded")
end)
Like raell said, this code does rotate the character. Try testing either version in a blank studio project.
I noticed that if the previousY was initialized as rootPart.Rotation.Y, the rotation wouldn’t start until I moved my character. You can try setting the previousY as a specific value to test if that changes the issue.
local character = game.Workspace:WaitForChild("youbigown")
local rootPart = character:WaitForChild("HumanoidRootPart")
local maxTurnRate = 10
local previousY = 20
local function rotateFun()
local newY = rootPart.Rotation.Y
local diff = newY - previousY
diff = math.clamp(diff,-maxTurnRate,maxTurnRate)
local newRotation = CFrame.new(character:GetPivot().Position) * CFrame.Angles(0, previousY + diff, 0)
character:PivotTo(newRotation)
previousY = newY
end
while true do
rotateFun()
task.wait(1)
end
i dont need a spin, i need to limit the turning control as said in the post, if you need an example try to find clips of the shield charge in tf2, charges forward, you cant turn over a certain speed.
What you’re currently trying to do is overriding the rotation each frame?
The overall problem is that from what I know, Roblox doesn’t allow you to edit the sensitivity of default rigs movement. Below are 2 methods that does not rely on frame overwriting.
tf2 is a mouse locked game from what I remember. You can have a mouse locked script that rotates the HumanoidRootPart based on mouse movement (X,Z), and in that script you can have a sensitivity variable in it. The sensitivity variable would be reduced when the charging is ongoing.
Below is a mockup snippet of the camera code from my game. It is a bit of a headache to prevent the camera going through walls though. I’m currently using raycasting, although it causes some camera snapping I haven’t been able to fix fully. If your game is 1st person, you can just set the CameraOffset to (0,0,0) and not have to worry about walls raycasting.
---top of script variables
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local cameraSensitivity = 0.3
local cameraOffset = Vector3.new(1.3,2,10)
local cameraRotationX = 0
local cameraRotationY = 0
local targetPart = character.HumanoidRootPart
--THIS SHOULD BE IN A RUNSERVICE LOOP
--Get the player mouse values
local delta = UserInputService:GetMouseDelta()
cameraRotationX = cameraRotationX - delta.Y * cameraSensitivity
cameraRotationY = cameraRotationY - delta.X * cameraSensitivity
--Clamp the vertical rotation to prevent flipping
cameraRotationX = math.clamp(cameraRotationX,-90,90)
--Rotate hrp
targetPart.CFrame = CFrame.new(targetPart.Position) * CFrame.Angles(0,math.rad(cameraRotationY),0)
--Position camera
camera.CFrame = CFrame.new(targetPart.Position) * CFrame.Angles(0,math.rad(cameraRotationY),0) * CFrame.Angles(math.rad(cameraRotationX),0,0) * CFrame.new(cameraOffset)
If you want a game where the mouse is not locked in the center, then you’d have create a script that detects player inputs (WASD) and swiftly tweens the HumanoidRootPart’s rotation in the direction corresponding to the key. You can then have a variable named sensitivityMultiplier that multiplies the rotation amount. When you have the rotation coded, you can then set the MoveDirection of the humanoid depending on the rotation. That is how I imagine Roblox movement is coded (I recently did this sort of simulation coding for my tornado). Since you have now coded it yourself, you can edit the sensitivity when needed.
In both scenarios you need to disable humanoid.Autorotate Humanoid.AutoRotate = false and then script custom rotation script.
you can choose where it starts by setting this in first loop iteration cameraRotationY = yourRotation
What is more important is that I haven’t added the sensitivityMultiplier (the difficult part). I’m gonna play around in studio to see if I can make it.
alright so here is the version with cameraRotationSpeed. You can set it to math.huge when you want to let the player rotate at any speed, whereas you can set it to for example 100 while the charging is happening. Though I will once again warn that if this game is 3rd person, this kind of script needs raycasting to prevent the camera from going through walls.
You can also just use this script as inspiration for your current system. The point is that this script limits the rotation by looking at how much time has passed and what the rotationSpeed is set as.
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local cameraSensitivity = 0.3
local cameraOffset = Vector3.new(1.5,2,10)
local cameraRotationX = 0
local cameraRotationY = 0
local cameraRotationSpeed = 100
local character = script.Parent
local targetPart = character:WaitForChild("HumanoidRootPart")
local UIS = game:GetService("UserInputService")
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
local runService = game:GetService("RunService")
local latestTime = tick()
runService.RenderStepped:Connect(function()
local currentTime = tick()
local passedTime = currentTime - latestTime
local delta = UIS:GetMouseDelta()
local targetChangeX = -delta.Y * cameraSensitivity
local targetChangeY = -delta.X * cameraSensitivity
local maxChange = cameraRotationSpeed * passedTime
targetChangeX = math.clamp(targetChangeX,-maxChange,maxChange)
targetChangeY = math.clamp(targetChangeY,-maxChange,maxChange)
cameraRotationX = cameraRotationX + targetChangeX
cameraRotationX = math.clamp(cameraRotationX,-90,90)
cameraRotationY = cameraRotationY + targetChangeY
targetPart.CFrame = CFrame.new(targetPart.Position) * CFrame.Angles(0,math.rad(cameraRotationY),0)
camera.CFrame = CFrame.new(targetPart.Position) * CFrame.Angles(0,math.rad(cameraRotationY),0) * CFrame.Angles(math.rad(cameraRotationX),0,0) * CFrame.new(cameraOffset)
latestTime = currentTime
end)
i think you need all of the elements to properly test this as it works fine in a separate place but i need to change stuff to put it into mine Charge spaghetti.rbxl (70.2 KB)
thats the place file im using, you will find everything inside of starterplayerscripts
Here it is. I centered the camera on the head so it’s 1st person. The charge now limits the rotation of the camera (you can limit it even more by reducing cameraRotationSpeed below 100). Charge spaghetti (youbigown).rbxl (69.9 KB)