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
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
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?
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:
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