How to Rotate Based on Direction of Movement/Velocity

Heya there!

So I made a flying system that (as far as I know) behaves and moves the same way as if you were walking. The direction of your movement is based on your inputs (WASD) and camera.

local UIS = game:GetService("UserInputService")
local RNS = game:GetService("RunService")
local PS = game:GetService("Players")

local player = PS.LocalPlayer
local char = player.Character
local root = char.PrimaryPart
local camera = workspace.CurrentCamera
local speed = 30
local velocity = Instance.new("BodyVelocity")
velocity.Parent = root
velocity.P = 10000
local gyro = Instance.new("BodyGyro")
gyro.Parent = root
gyro.D = 30
local isFlying = false

local toggleKey = Enum.KeyCode.Q

local function MovementToCameraSpace()
	local keys = {
		[Enum.KeyCode.W] = Enum.NormalId.Front,
		[Enum.KeyCode.S] = Enum.NormalId.Back,
		[Enum.KeyCode.A] = Enum.NormalId.Left,
		[Enum.KeyCode.D]= Enum.NormalId.Right
	}
	local dir = Vector3.zero
	
	for i,v in pairs(keys) do
		if UIS:IsKeyDown(i) then
			dir += Vector3.FromNormalId(v)
		end
	end
	
	return if dir.Magnitude > 0 then dir.Unit else dir
end

local function MovementToWorldSpace()
	local dir = camera.CFrame:VectorToWorldSpace(MovementToCameraSpace())
	
	return if dir.Magnitude > 0 then dir.Unit else dir
end

local function UpdateConstraint()
	velocity.MaxForce = if isFlying then Vector3.one * math.huge else Vector3.zero
	gyro.MaxTorque = if isFlying then Vector3.one * math.huge else Vector3.zero
	
	if not isFlying then
		return
	end
	
	local dir = MovementToWorldSpace() * speed

	velocity.Velocity = dir
	gyro.CFrame = CFrame.new() -- what do i do?
end

local function UpdateInput(input, typing)
	if typing then
		return
	end
	
	if input.KeyCode == toggleKey then
		isFlying = not isFlying
	end
end

RNS.RenderStepped:Connect(UpdateConstraint)
UIS.InputBegan:Connect(UpdateInput)

Now here’s the question. How do I make the character rotate based on the direction of where the player is moving towards? Here’s an example of what I mean:

image

1 Like

You can probably just use the humanoid movedireciton for that

2 Likes

How would I make the character turn using MoveDirection?

I just accidentally found out that I don’t even need BodyGyro…

The truth is, setting BodyVelocity already rotates it towards the direction of the movement. The only reason as to why it wasn’t rotating was LITERALLY BECAUSE OF THE BODYGYRO-

Here is the final script (without BodyGyro):

local UIS = game:GetService("UserInputService")
local RNS = game:GetService("RunService")
local PS = game:GetService("Players")

local player = PS.LocalPlayer
local char = player.Character
local root = char.PrimaryPart
local camera = workspace.CurrentCamera
local speed = 30
local velocity = Instance.new("BodyVelocity")
velocity.Parent = root
velocity.P = 10000
local isFlying = false

local toggleKey = Enum.KeyCode.Q

local function MovementToCameraSpace()
	local keys = {
		[Enum.KeyCode.W] = Enum.NormalId.Front,
		[Enum.KeyCode.S] = Enum.NormalId.Back,
		[Enum.KeyCode.A] = Enum.NormalId.Left,
		[Enum.KeyCode.D]= Enum.NormalId.Right
	}
	local dir = Vector3.zero

	for i,v in pairs(keys) do
		if UIS:IsKeyDown(i) then
			dir += Vector3.FromNormalId(v)
		end
	end

	return if dir.Magnitude > 0 then dir.Unit else dir
end

local function MovementToWorldSpace()
	local dir = camera.CFrame:VectorToWorldSpace(MovementToCameraSpace())

	return if dir.Magnitude > 0 then dir.Unit else dir
end

local function UpdateConstraint()
	velocity.MaxForce = if isFlying then Vector3.one * 100000 else Vector3.zero

	if not isFlying then
		return
	end

	local dir = MovementToWorldSpace() * speed

	velocity.Velocity = dir
end

local function UpdateInput(input, typing)
	if typing then
		return
	end

	if input.KeyCode == toggleKey then
		isFlying = not isFlying
	end
end

RNS.RenderStepped:Connect(UpdateConstraint)
UIS.InputBegan:Connect(UpdateInput)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.