Player smooth movement

Hello, I wrote a script to create smoother character rotation using AlignOrientation and to prevent character bugs with shiftlock, but I have some issues. For example, the character’s rotation not syncing with the movement direction makes it look more awkward and strange.

My goal is to achieve smoother character rotation and to make shiftlock smoother, but as I mentioned, the character synchronization isn’t working. The character moves in the direction the camera is facing instead of the direction it’s looking.

My attempted solutions: updating the player module, adding AlignOrientation, and adding a movement script.

This is AlignOrientation script

-- LocalScript
local player = game.Players.LocalPlayer -- Get the local player
local mouse = player:GetMouse() -- Get the mouse object for player interactions
wait(1) -- Wait for a second to ensure everything is loaded

local Character = player.Character or player.CharacterAdded:Wait() -- Get the character or wait for it to load
local Hrp = Character:WaitForChild("HumanoidRootPart") -- Get the HumanoidRootPart of the character
local RootAttachment = Hrp:WaitForChild("RootAttachment") -- Get the RootAttachment from the HumanoidRootPart

local runService = game:GetService('RunService') -- Get the RunService for frame updates

-- Create Attachments and AlignOrientation for smoother rotation
local alignOrientation = Instance.new('AlignOrientation', Hrp) -- Create a new AlignOrientation instance
alignOrientation.Attachment0 = RootAttachment -- Set the first attachment
alignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment -- Set the alignment mode to one attachment

-- Set MaxAngularVelocity and MaxTorque for fast rotation
alignOrientation.MaxAngularVelocity = math.huge -- Set a very high value for maximum angular velocity
alignOrientation.MaxTorque = math.huge -- Set a very high value for maximum torque

-- Function to find the angle between two points
local function findAngle(positionA, direction)
	local targetPosition = positionA + direction.Unit -- Calculate the target position using the direction
	local CF = CFrame.new(positionA, targetPosition) -- Create a CFrame from positionA to targetPosition
	return CF:ToEulerAnglesYXZ() -- Return the target angle in YXZ format
end

-- Update continuously with RenderStepped
runService.RenderStepped:Connect(function()
	local cameraDirection = workspace.CurrentCamera.CFrame.LookVector -- Get the camera's forward direction
	local targetOrientationX, targetOrientationY, targetOrientationZ = findAngle(Hrp.Position, cameraDirection) -- Find the target orientation angles

	-- Update the alignOrientation.CFrame with the new target orientation
	alignOrientation.CFrame = CFrame.Angles(0, targetOrientationY, 0) -- Use the Y angle for rotation
end)

movement script

local targetMoveVelocity = Vector3.new()
local moveVelocity = Vector3.new()
local Dir = CFrame.Angles(0,0,0)
local moveAcceleration = 5
local stopDecel = 10

local plr = game:GetService("Players").LocalPlayer
local RunS = game:GetService("RunService")
local InputS = game:GetService("UserInputService")
local CAS = game:GetService("ContextActionSe
rvice")
local ctrlModule = require(plr:WaitForChild("PlayerScripts").PlayerModule:WaitForChild("ControlModule"))

local character = plr.Character or plr.CharacterAdded:Wait()
local camera = game.Workspace.CurrentCamera

local function lerp(a, b, t) return a + (b - a) * t end

local function getWalkDirectionCameraSpace()
	local walkDir = ctrlModule:GetMoveVector()

	if walkDir.Magnitude > 0 then
		walkDir = Vector3.new(walkDir.X, 0, walkDir.Z).Unit * walkDir.Magnitude
		if walkDir.Magnitude > 1 then
			walkDir = walkDir.Unit
		end
	end

	return walkDir
end

local function getWalkDirectionWorldSpace()
	local walkDir = camera.CFrame:VectorToWorldSpace(getWalkDirectionCameraSpace())

	if walkDir.Magnitude > 0 then
		walkDir = Vector3.new(walkDir.X, 0, walkDir.Z).Unit * walkDir.Magnitude
		if walkDir.Magnitude > 1 then
			walkDir = walkDir.Unit
		end
	end

	return walkDir
end

local function noY(vec:Vector3)
	return Vector3.new(vec.X,0,vec.Z)
end

local function updateMovement(dt)
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		local moveDir = getWalkDirectionWorldSpace() 
		local deceleration = lerp(moveAcceleration, stopDecel, 1 - moveDir.Magnitude)
		targetMoveVelocity = moveDir
		moveVelocity = lerp(moveVelocity, targetMoveVelocity, math.clamp(dt * deceleration, 0, 1))
		humanoid:Move(moveVelocity)
	end
end

RunS.RenderStepped:Connect(updateMovement)

try to make the alignoreintation responsiveness higher

Turn off AutoRotate in the character’s humanoid this should allow the character to move in all directions.

1 Like

Thank you for your suggestion, but unfortunately, it continues even though I have disabled auto-rotate. It didn’t work; the character is not moving in the direction it is facing, which is strange.

1 Like

Ok the reenable it if you wish for the character to face in the direction it moves you will have to combine the two scripts.

EDIT: The two need combining because for this you will need the “moveVelocity” variable to use in place of the cameras lookvector.

Slightly late to this, sorry for the bump if you already solved the issue.

Is autorotate on? Make sure it’s off.
Try setting alignorientation to rigedityenabled=true and see if it works that way. If it does, then you need to bump up your responsiveness.