Get character's Moving Direction

Hello, I’m currently working on my own fighting game. I’m trying to make the HumanoidRootPart turn where the player is walking.

What I’ve been doing is this:
> A/D Pressed -> MovementModule('Left' or 'Right'): returns (-90 or 90) -> Angle = Returned Angle

If you don’t want to read everything I’m going to say. Here’s a quick resume

I want is to rotate the character’s body in the direction they’re moving

Below I will show you my code for the context of my current work.
If you don’t need it, just skip to the HumanoidRootPart/CFrame Handler block.


The Code

If this is unclear let me show you the code that handles the Inputs.

Inputs Handler

local Angle = 90
... -- Useless lines

-- This table keeps track of the last state of pressed keys
local PressedKeys = {} -- I removed what's inside so the script isn't too big

-- Table containing all the key combinations and their associated actions
local Combos = {
	{Keys = "F", Move = "Parry", OnUp = true},  -- Example combo
	-- Other key combos...
}

-- Function to handle key combinations
local function HandleCombos(Key:string, NewState:boolean)
	for _, Combo in ipairs(Combos) do
		-- Checking if the pressed key matches any defined combo
		if Combo.Keys == Key or (type(Combo.Keys) == 'table' and table.find(Combo.Keys, Key)) then
			local AllKeysDown = true
			-- Checking if all keys in the combo are pressed
			if type(Combo.Keys) == 'table' then
				AllKeysDown = true
				for _, IKey in ipairs(Combo.Keys) do
					-- If any key in the combo is not pressed, set AllKeysDown to false
					if not PressedKeys[IKey] or not PressedKeys[IKey].LastTick or tick() - PressedKeys[IKey].LastTick > (Combo.Expire or math.huge) then
						AllKeysDown = false
						break
					end
				end
			end
			-- If all keys are pressed and the combo is triggered on key release, execute associated action
			if AllKeysDown and Combo.OnUp then
				local returned = MovementsModule[Combo.Move](LocalCharacter, NewState)
				if returned then
					-- Send movement data over network and update the HumanoidRootPart position
					Network.Send('Combat', Combo.Move, returned)
					HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.Position) * returned
				end
			-- If all keys are pressed and the combo is triggered on key press, execute associated action
			elseif AllKeysDown and NewState then
				MovementsModule[Combo.Move](LocalCharacter)
			end
		end
	end
end

-- Function to convert input state to boolean
local function UserInputStateToBool(InputState: Enum.UserInputState)
	return InputState == Enum.UserInputState.Begin
end

-- Function to handle input changes
local function ChangeInput(Input: InputObject, InputState: Enum.UserInputState)
	local Key = if Input.KeyCode.Name == 'Unknown' then Input.UserInputType.Name else Input.KeyCode.Name
	if PressedKeys[Key] then
		local IsPressed = UserInputStateToBool(InputState)
		PressedKeys[Key].IsPressed = IsPressed
		PressedKeys[Key].LastTick = tick()
		-- Handle key combinations based on input changes
		HandleCombos(Key,IsPressed)
	end
end

-- Function to unbind movement keys (W & S) since I'm using a 2D style
local function UnbindKeys()
	local FowardMovement = Enum.PlayerActions.CharacterForward
	local BackwardMovement = Enum.PlayerActions.CharacterBackward

	local function Sink(_, InputState: Enum.UserInputState, InputObject: InputObject)
		local StringToBool = if InputState.Name == 'End' then false else true
		ChangeInput(InputObject, StringToBool)
		return Enum.ContextActionResult.Sink
	end

	-- Unbind movement keys
	ContextActionService:BindAction("SinkFowardMovement", Sink, false, FowardMovement)
	ContextActionService:BindAction("SinkBackwardMovement", Sink, false, BackwardMovement)
end

-- Unbind movement keys
UnbindKeys()

-- Connect input events
UserInputService.InputBegan:Connect(function(Input: InputObject, GameProcessedEvent: boolean)
	if GameProcessedEvent then return end -- Check if input is processed by another script
	ChangeInput(Input, Enum.UserInputState.Begin)
end)

UserInputService.InputEnded:Connect(function(Input: InputObject, GameProcessedEvent: boolean)
	if GameProcessedEvent then return end -- Check if input is processed by another script
	ChangeInput(Input, Enum.UserInputState.End)
end)

HumanoidRootPart/CFrame Handler

RunService:BindToRenderStep('HRPLock',0, function()
	local Position = Vector3.new(HRP.Position.X,HRP.Position.Y,Settings.ZAxis) 
    --^ This is to ensure that the Character doesn't move on the Z axis since
    -- the game is "2D"
	HRP.CFrame = CFrame.new(Position) * --CFrame.Angles(0, math.rad(Angle), 0)
end)

Movement Module

function MovementsModule.LookLeft()
	if not Allowed('Turn') then return end
	return 90 --CFrame.Angles(0, math.rad(90), 0)
end
function MovementsModule.LookRight()
	if not Allowed('Turn') or not Character:GetAttribute('CanTurn') then return end
	return -90 --CFrame.Angles(0, math.rad(-90), 0)
end

The code that I made is buggy and sometimes doesn’t work. I want to scrap the LookRight & LookLeft function and check in which direction the player is moving and rotate it in that direction.

If you have any questions don’t hesitate, I can provide you with more of the code if needed

Is this helpful in anyway.

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

while true do
	local velocity = character.HumanoidRootPart.Velocity
	local moveDirection = velocity.unit
	--
	wait(0.1)
end

1 Like

This worked for now, if anyone has a better solution you can PM me

function VelocityToOrientation(Velocity:number)
	if Velocity > 0 then
		return -90
	elseif Velocity < 0 then
		return 90
	elseif Velocity == 0 then
		return HumanoidRootPart.CFrame.Rotation.X
	end
end
Network.Add('StartCombat',function(Settings:{ZAxis:number,HumanoidRootParts:{[any]:Part}},Opponent:Player)
	if not Opponent then return end
	local HRP = HumanoidRootPart
	local Opponent_HRP = Opponent:FindFirstChild('HumanoidRootPart')
	if not Opponent_HRP then return end
	RunService:BindToRenderStep('HRPLock', -1, function()
		local Position = Vector3.new(HRP.Position.X,HRP.Position.Y,Settings.ZAxis)
		--// Lock on opponent
		--local LookAt = Vector3.new(Opponent_HRP.Position.X, HRP.Position.Y, Opponent_HRP.CFrame.Z)
		HRP.CFrame = CFrame.new(Position) * CFrame.Angles(0,math.rad(VelocityToOrientation(HRP.Velocity.X)),0)
	end)
	DynamicCamera(Settings.HumanoidRootParts)
	wait()
	LogInputs = true
end)

I used thMoveDirectionat to tell direction… figured you already tried

1 Like

have you tried Humanoid.MoveDirection

2 Likes