Choosing a direction to move based on the way the camera is facing

Right now I am currently making a multiplayer racing game where everyone is placed into an orb and has to roll to the finish line while avoiding obstacles and collecting fruits. I am now scripting the movement system for the orbs but I have run into a bit of a problem.

I started on using BodyAngularVelocity for the mover, and made it so the orbs would be controlled via WASD. However, I quickly realised that BodyAngularVelocity would not change the direction it moved forward to the way the camera was facing by default, and I would have to script that myself. However, I am very lacking when it comes to camera scripting, and I do not know a good way to execute this.

So, my question is there a good way to make the player orb go forward in the way the camera is facing using BodyAngularVelocity or do I need to switch to an alternative movement system in order to execute what I need?

Here is my current code for reference (the input is handed to the server via RemoteFunction)

	local char = workspace:WaitForChild(plr.Name)
	local bav = char.Ball.BodyAngularVelocity
	if letgo == false then
		if key == Enum.KeyCode.W then
			bav.AngularVelocity = Vector3.new(bav.AngularVelocity.X, bav.AngularVelocity.Y, 7)
		elseif key == Enum.KeyCode.S then
			bav.AngularVelocity = Vector3.new(bav.AngularVelocity.X, bav.AngularVelocity.Y, -7)
		elseif key == Enum.KeyCode.A then
			bav.AngularVelocity = Vector3.new(7, bav.AngularVelocity.Y, bav.AngularVelocity.Z)
		elseif key == Enum.KeyCode.D then
			bav.AngularVelocity = Vector3.new(-7, bav.AngularVelocity.Y, bav.AngularVelocity.Z)
		end
	elseif letgo == true then
		if key == Enum.KeyCode.W then
			bav.AngularVelocity = Vector3.new(bav.AngularVelocity.X, bav.AngularVelocity.Y, 0)
		elseif key == Enum.KeyCode.S then
			bav.AngularVelocity = Vector3.new(bav.AngularVelocity.X, bav.AngularVelocity.Y, 0)
		elseif key == Enum.KeyCode.A then
			bav.AngularVelocity = Vector3.new(0, bav.AngularVelocity.Y, bav.AngularVelocity.Z)
		elseif key == Enum.KeyCode.D then
			bav.AngularVelocity = Vector3.new(0, bav.AngularVelocity.Y, bav.AngularVelocity.Z)
		end
	end
end
2 Likes

I recomend switching to CFrame and setting the Y rotation of the orb to the LookVector of the camera being used on the camera, smth like this…

local Camera = workspace.CurrentCamera

game:GetService("RunService").RenderStepped:Connect(function()
   local CameraLook = Camera.CFrame.LookVector
   Remote:FireServer(CameraLook)
end)

This returns a Vector3 which you can then, on the server, set the rotation of the orb on the Y axis

LookVector, is a bit more advanced, but in this context, it’s where the camera is pointed

ps `` am i a joke to you

Okay, I will try that, but what’s the best way to use CFrame to move the ball while still keeping physics such as gravity so if the ball goes off the platform it will fall into the void and such?

If it’s just rotation, BodyGyro

After some investigation into CFrame it appears it would not be ideal for what I am trying to do as it would be very choppy and laggy. Here’s a video of what I am trying to make move for reference:

1 Like

As stated I just need it to be able to go forwards in the direction the camera is facing, backwards in the opposite direction, etc

I actually got a friend to help me figure it out. Thanks for the help, anyway.

And how exactly did that friend help you out?

We made it so it would change the AngularVelocity based on the Camera’s LookVector + a control value which the keyboard controls changed. The camera lookvector which would get sent to the server with a RemoteFunction, as well as the keyboard controls. We also added a roll strength value so we could easily change the speed of the ball. Here is the script for anyone who is wondering how we did it:

local remotes = game.ReplicatedStorage.Remotes

local rollStrength = 5

game.Players.PlayerAdded:Connect(function(player)
	local controls = Instance.new("Vector3Value", player)
	controls.Name = "UserInput"
	local camcf = Instance.new("CFrameValue", player)
	camcf.Name = "CameraCF"	
end)

remotes.ControlFunc.OnServerInvoke = function(plr, key, letgo)
	local camcf = plr:FindFirstChild("CameraCF")
	local char = workspace:WaitForChild(plr.Name)
	local controls = plr:FindFirstChild("UserInput")
	local bav = char.Ball.BodyAngularVelocity
	if letgo == false then
		if key == Enum.KeyCode.W then
			controls.Value = controls.Value + Vector3.new(0,1,0)
		elseif key == Enum.KeyCode.S then
			controls.Value = controls.Value + Vector3.new(0,-1,0)
		elseif key == Enum.KeyCode.A then
			controls.Value = controls.Value + Vector3.new(-1,0,0)
		elseif key == Enum.KeyCode.D then
			controls.Value = controls.Value + Vector3.new(1,0,0)
		end
	elseif letgo == true then
		if key == Enum.KeyCode.W then
			controls.Value = controls.Value - Vector3.new(0,1,0)
		elseif key == Enum.KeyCode.S then
			controls.Value = controls.Value - Vector3.new(0,-1,0)
		elseif key == Enum.KeyCode.A then
			controls.Value = controls.Value - Vector3.new(-1,0,0)
		elseif key == Enum.KeyCode.D then
			controls.Value = controls.Value - Vector3.new(1,0,0)
		end
	end
	bav.AngularVelocity = ((camcf.Value.LookVector * controls.Value.X) + (camcf.Value.RightVector * -controls.Value.Y)) * rollStrength
end

remotes.CamFunc.OnServerInvoke = function(plr, cf)
	local camcf = plr:FindFirstChild("CameraCF")
	local controls = plr:FindFirstChild("UserInput")
	local char = workspace:WaitForChild(plr.Name)
	local bav = char.Ball.BodyAngularVelocity
	if typeof(cf) ~= "CFrame" then plr:Kick() return end
	camcf.Value = cf
	bav.AngularVelocity = ((camcf.Value.LookVector * controls.Value.X) + (camcf.Value.RightVector * -controls.Value.Y)) * Vector3.new(rollStrength, 0, rollStrength)
end
1 Like