VectorForce drifting

I’ve been designing a simple controller for a space ship. I’m using a VectorForce to apply the velocity I need. However, I’ve found that the ship “drifts” when turning.

It’s a little hard to explain so I’ve included a GIF of it in action.

Imgur: The magic of the Internet.

I know I could take the ship’s current velocity then compare it with the VectorForce’s velocity to counteract the drift but I was wondering if there is any other… simpler solution.

Thanks

4 Likes

Well, I’m not too keen on this topic to be totally honest, but are you sure that you aren’t accidentally applying the velocity horizontally in some accidental location?

It would also be quite helpful if we could see the part of your code which uses VectorForce!

1 Like

I doubt I am doing that, but I have done dumber things in the past so…
I figured out with some testing that in order to go forward you need to apply a force to the negative z direction.

Here’s my local script which gets input from the player and then sends that input to a server script. And yes yes yes I know it’s extremely messy and using a LOT of repeat code. But at the moment I’m just playing around seeing what I can do, so I’m not really focused on that.

Local Script
local input = game:GetService("UserInputService")
local velocity = Vector3.new()
local turningVelocity = Vector3.new()
local maxSpeed = script.Parent.RootShipPart.MaxSpeed.Value
local VelocityChangeEvent = game.ReplicatedStorage.VelocityChange

local up = false
local down = false
local left = false
local right = false
local speedUp = false
local speedDown = false
local rollLeft = false
local rollRight = false

-- local script

-- recieves when inputs begin and tells script that
input.InputBegan:Connect(function(inputObject, gameProcessedEvent)
	if gameProcessedEvent == true then return end
	
	if (inputObject.KeyCode == Enum.KeyCode.W)then up = true end
	if (inputObject.KeyCode == Enum.KeyCode.S)then down = true end
	if (inputObject.KeyCode == Enum.KeyCode.Q)then left = true end
	if (inputObject.KeyCode == Enum.KeyCode.E)then right = true end
	if (inputObject.KeyCode == Enum.KeyCode.LeftShift)then speedUp = true end
	if (inputObject.KeyCode == Enum.KeyCode.LeftControl)then speedDown = true end
	if (inputObject.KeyCode == Enum.KeyCode.A)then rollLeft = true end
	if (inputObject.KeyCode == Enum.KeyCode.D)then rollRight = true end
end)

-- recieves when inputs end and tells script that - together with the above code we find when a key is being held down
input.InputEnded:Connect(function(inputObject, gameProcessedEvent)
	if gameProcessedEvent == true then return end
	
	if (inputObject.KeyCode == Enum.KeyCode.W)then up = false end
	if (inputObject.KeyCode == Enum.KeyCode.S)then down = false end
	if (inputObject.KeyCode == Enum.KeyCode.Q)then left = false end
	if (inputObject.KeyCode == Enum.KeyCode.E)then right = false end
	if (inputObject.KeyCode == Enum.KeyCode.LeftShift)then speedUp = false end
	if (inputObject.KeyCode == Enum.KeyCode.LeftControl)then speedDown = false end
	if (inputObject.KeyCode == Enum.KeyCode.A)then rollLeft = false end
	if (inputObject.KeyCode == Enum.KeyCode.D)then rollRight = false end
end)

-- takes the above codes outputs and does some math to figure out what to send to the "VelocityChangeEvent" script (which is the server sided script of this exchange)
while true do
	if speedUp == true then if velocity.Z-0.1 > maxSpeed *-1 then velocity = velocity + Vector3.new(0, 0, -0.1) end end
	if speedDown == true then if velocity.Z+0.1 < maxSpeed*0.6 then velocity = velocity + Vector3.new(0, 0, 0.1) end end
	if right == true then if turningVelocity.Z-0.1 > maxSpeed*-0.1 then turningVelocity = turningVelocity + Vector3.new(0, 0, -0.005) end end
	if left == true then if turningVelocity.Z+0.1 < maxSpeed*0.1 then turningVelocity = turningVelocity + Vector3.new(0, 0, 0.005) end end
	if up == true then if turningVelocity.X+0.1 < maxSpeed*0.1 then turningVelocity = turningVelocity + Vector3.new(0.005, 0, 0) end end
	if down == true then if turningVelocity.X-0.1 > maxSpeed*-0.1 then turningVelocity = turningVelocity + Vector3.new(-0.005, 0, 0) end end
	if rollLeft == true then if turningVelocity.Y+0.1 < maxSpeed*0.1 then turningVelocity = turningVelocity + Vector3.new(0, 0.005, 0) end end
	if rollRight == true then if turningVelocity.Y-0.1 > maxSpeed*-0.1 then turningVelocity = turningVelocity + Vector3.new(0, -0.005, 0) end end
	
	if turningVelocity.X+0.003 < 0 and down == false then turningVelocity = turningVelocity + Vector3.new(0.004, 0, 0) end
	if turningVelocity.X-0.003 > 0 and up == false then turningVelocity = turningVelocity + Vector3.new(-0.004, 0, 0) end
	if turningVelocity.Y+0.003 < 0 and rollRight == false then turningVelocity = turningVelocity + Vector3.new(0, 0.004, 0) end
	if turningVelocity.Y-0.003 > 0 and rollLeft == false then turningVelocity = turningVelocity + Vector3.new(0, -0.004, 0) end
	if turningVelocity.Z+0.003 < 0 and right == false then turningVelocity = turningVelocity + Vector3.new(0, 0, 0.004) end
	if turningVelocity.Z-0.003 > 0 and left == false then turningVelocity = turningVelocity + Vector3.new(0, 0, -0.004) end
	VelocityChangeEvent:FireServer(velocity, turningVelocity)
	wait()
end

And here is the server-sided script which actually applies the force to the player.

Summary
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local velocityChange = ReplicatedStorage:WaitForChild("VelocityChange")

local function velocityChangeFunction(player, velocity, rotVelocity)
	local rotController = game.Workspace[player.Name].RootShipPart.RotationNode
	local movController = game.Workspace[player.Name].RootShipPart.MovementNode

	movController.Force = velocity -- apply a force using VectorForce
	rotController.AngularVelocity = rotVelocity -- apply a force using AngularVelocity
end

velocityChange.OnServerEvent:Connect(velocityChangeFunction)

Thanks again!

2 Likes