Transforming unitized vector3 to be relative to lookvector of camera

I’m trying to create a custom movement system via ControllerManagers. However, when moving, the character only moves relative to the world axis. I want to transform the movement vector to be relative to where the camera is facing.

There isn’t much documentation about controllermanagers in general and i don’t think any level of google-fu can bring relevant answers to this problem. I’ve tried setting the FacingDirection of the manager but that doesn’t seem to do anything.

thanks (^:

relevant code:

--declare variables
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Character = Players.LocalPlayer.Character
local Camera = workspace.CurrentCamera

--Set camera
Camera.CameraSubject = Character:WaitForChild("Head")
Camera.CameraType = Enum.CameraType.Custom


--Set movement functions
local ZERO_VECTOR3 = Vector3.new()

local Manager = Character.ControllerManager
local forwardValue  = 0
local backwardValue = 0
local leftValue = 0
local rightValue = 0


function UpdateMovement(inputState)
	if inputState == Enum.UserInputState.Cancel then
		Manager.MovingDirection = ZERO_VECTOR3 
	else
		Manager.MovingDirection = Vector3.new(leftValue + rightValue, 0, forwardValue + backwardValue)
	end
end


local handleMoveForward = function(actionName, inputState, inputObject)
	forwardValue = (inputState == Enum.UserInputState.Begin) and -1 or 0
	UpdateMovement(inputState)
end

local handleMoveBackward = function(actionName, inputState, inputObject)
	backwardValue = (inputState == Enum.UserInputState.Begin) and 1 or 0
	UpdateMovement(inputState)
	return Enum.ContextActionResult.Pass
end

local handleMoveLeft = function(actionName, inputState, inputObject)
	leftValue = (inputState == Enum.UserInputState.Begin) and -1 or 0
	UpdateMovement(inputState)
	return Enum.ContextActionResult.Pass
end

local handleMoveRight = function(actionName, inputState, inputObject)
	rightValue = (inputState == Enum.UserInputState.Begin) and 1 or 0
	UpdateMovement(inputState)
	return Enum.ContextActionResult.Pass
end


--bind events
game:GetService("ContextActionService"):BindAction("Forward",handleMoveForward,false,Enum.KeyCode.W)
game:GetService("ContextActionService"):BindAction("Left",handleMoveLeft,false,Enum.KeyCode.A)
game:GetService("ContextActionService"):BindAction("Right",handleMoveRight,false,Enum.KeyCode.D)
game:GetService("ContextActionService"):BindAction("Back",handleMoveBackward,false,Enum.KeyCode.S)

I suppose this should work

Manager.MovingDirection = cameraCF:VectorToWorldSpace(Vector3.new(leftValue + rightValue, 0, forwardValue + backwardValue))

If you’re not familiar with cframes, CFrame:VectorToWorldSpace(vec) changes the direction that you give it to be relative to the cframe you call it on, so in your case it’d turn the move direction to be relative to the camera, so Vector3.new(1, 0, 0) would be right relative to the camera.
Tho you’d probably also want to remove the Y axis after doing this as well, And then apply .Unit to make sure it’d be with a length of 1.

1 Like