I need a way to get the movement direction of the player and have it return a string such as: “Forward”, “Backward”, “DiagnalRight”, ect…
Insight to why
I am developing an RPG with a combat system similar shadow fight 2.
as you can see in this gif; it’s a 2d game with an 8-Directional movement system,
which is why I also need to know if the player is moving diagnaly.
The only post i’ve found on this was here which never found sulotion, and the code didn’t work for me. Furthermore, It doesn’t cover diagnal movement.
relevent code:
local ContextActionService = game:GetService("ContextActionService")
local player = game:GetService("Players").LocalPlayer
local MoveVector = require(player:WaitForChild("PlayerScripts").PlayerModule:WaitForChild("ControlModule"))
local function getMovement()
local hrp = player.Character.HumanoidRootPart
local movementDirection = workspace.CurrentCamera.CFrame:VectorToObjectSpace(player.Character.Humanoid.MoveDirection).Unit --not being used
local lookVector = player.Character.Humanoid.MoveDirection:Dot(hrp.CFrame.LookVector)-- up down
local rightVector = player.Character.Humanoid.MoveDirection:Dot(hrp.CFrame.RightVector)-- sides
print(lookVector)
print(rightVector)
if lookVector > 0 then
warn("Forward")
elseif lookVector < 0 then
warn"Backward"
end
--haven't tried the left & right movement yet because this doesnt even work
end
PlayerMovment = {}
function PlayerMovment.setBattleMovement()
ContextActionService:BindAction("Gamepd", getMovement, false,
Enum.UserInputType.Gamepad1, Enum.UserInputType.Touch
)
end
return PlayerMovment
Are you looking for raw player inputs (e.g. w, a, s, d, wa, wd, as, sd, but it also works for mobile), world relative movement directions, or character relative movement directions?
You can get a name for the direction a player is moving by using a Dot product to compare different directions.
For example:
local directions = {
{Vector3.new(0,0,1), "Forward"},
{Vector3.new(1,0,1).Unit, "ForwardRight"},
{Vector3.new(1,0,0), "Right"},
-- TODO: Fill out the other directions
}
local function getDirectionName(direction)
direction = direction.Unit
local maxDot = -1 * math.huge
local maxName = ""
for _, possibleDirectionPair in ipairs(directions) do
-- Checks how similar the two directions are
dot = direction:Dot(possibleDirectionPair[1])
if dot > maxDot then
maxDot = dot
maxName = possibleDirectionPair[2]
end
end
return maxName
end
You can then get the movement direction you’re looking for based on what you want:
You can get raw input directions from the PlayerModule (there are some topics on the forums for this)
You can get the world-relative direction the character is moving from Humanoid.MoveDirection
You can a character relative direction using HumanoidRootPart.CFrame:VectorToObjectSpace(Humanoid.MoveDirection)
Thank you so much! This sulotion works for my needs, and is expadable. Only question I was wondering is what does .Unit do for the diagnals if you already get the unit in the function? During testing I found out that why but I dont understand how normalizing before the function changes it. Cheers!
The dot product result depends on the length of the two vectors.
In the function, the input vector is normalized (set to a length of one).
However, for it to be a fair comparison between all the directions, all of those also have to be a length of one. That’s why I added the .Unit in the table, so that even the diagonals have a length of one (otherwise they’d have a length of root 2).
If you didn’t want to do that in the table, you could change this line: