Velocity Not Working Randomly

So, I’m making a starship flight system for my space exploration game, and I’m using align orientations and linear velocitys (although ive tried multiple methods of changing velocity, same overall result)
Code below if needed:

local plr = game:GetService("Players").LocalPlayer
local camera = workspace.CurrentCamera
local mouse = plr:GetMouse()

local summonDB = false

local replicatedStorage = game:GetService("ReplicatedStorage")
local tm = require(replicatedStorage.Modules.tweenModule)

local runService = game:GetService("RunService")

local CONTROL_TABLE = {
	[Vector3.new(0,0,-1)] = Enum.KeyCode.W,
	[Vector3.new(0,0,1)] = Enum.KeyCode.S,
	[CFrame.Angles(0,math.rad(2),0)] = Enum.KeyCode.A, 
	[CFrame.Angles(0,math.rad(-2),0)] = Enum.KeyCode.D,
	[Vector3.new(0,1,0)] = Enum.KeyCode.Space, 
	[Vector3.new(0,-1,0)] = Enum.KeyCode.C,  
}


local IGNORE_NAMES = {
	"Center",
	"Camera",
	"movePart"
}

local module = {}

local function findInTable(haystack, needle)
	for i, v in pairs(haystack) do
		if i == needle then
			return v
		elseif v == needle then
			return i
		end
	end
end


local function setCameraMode(toggle)
	local mode = toggle and Enum.CameraType.Scriptable or Enum.CameraType.Custom

	repeat task.wait()
		camera.CameraType = mode
	until camera.CameraType == mode
end

function module.summonShip(shipName)
	if summonDB == true then return nil end
	print("summoning ship")
	summonDB = true
	local potentialShip = workspace.ships:FindFirstChild(plr.Name)
	if potentialShip then
		potentialShip:Destroy()	
	end
	local potentialShadowShip = replicatedStorage.Remotes.getShadowShip:InvokeServer(shipName)
	local shadowShip = potentialShadowShip and potentialShadowShip or workspace.shadowShips:WaitForChild(plr.Name)
	
	if not shadowShip then warn("no ship, terminating") return nil end
	shadowShip.PrimaryPart.Attachment:Destroy()
	mouse.TargetFilter = shadowShip
	for _, part in pairs(shadowShip:GetDescendants()) do
		if part:IsA("BasePart") or part:IsA("UnionOperation") then
			if not table.find(IGNORE_NAMES, part.Name) then
				part.Transparency = .5
				part.Color = Color3.new(0.113725, 0.984314, 1)
				part.CanCollide = false
			end
		end
	end



	mouseLoop = runService.RenderStepped:Connect(function()
		shadowShip:SetPrimaryPartCFrame(CFrame.new(mouse.Hit.Position))
	end)

	local function onClick()
		local placeCFrame = shadowShip.PrimaryPart.CFrame

		mouseLoop:Disconnect()
		shadowShip:Destroy()
		replicatedStorage.Remotes.summonShipEvent:FireServer(placeCFrame, shipName)
		summonDB = false	
	end

	clickDetect = mouse.Button1Down:Connect(function()
		onClick()
		clickDetect:Disconnect()
	end)
end

function module.shipController()
	local functions = {}
	local ship = workspace.ships:FindFirstChild(plr.Name)

	if not ship then return nil end
	mouse.TargetFilter = ship
	local primaryPart = ship.PrimaryPart
	local cameraPart = ship:FindFirstChild("Camera")
	local movePart = ship:FindFirstChild("movePart")

	local controlsUnlocked = false
	local movementMultiplier = 20

	local cframeloop
	local alignLoop 
	local loop
	local att
	local linear
	local align


	workspace.Gravity = 0
	if not movePart then

		-- movepart doesnt exist:

		movePart = Instance.new("Part")
		movePart.Name = "movePart"
		movePart.Transparency = 0
		movePart.CanCollide = false
		movePart.Anchored = false
		movePart.Parent = ship
		movePart.CFrame = primaryPart.CFrame


		-- create att:
		att = Instance.new("Attachment")
		att.Name = 'att'
		att.Parent = movePart
		att.WorldCFrame = movePart.CFrame

		-- linear velocity
		linear = Instance.new("LinearVelocity")
		linear.Name = 'linear'
		linear.Parent = att
		linear.Attachment0 = att
		linear.MaxForce = 10000
		linear.RelativeTo = Enum.ActuatorRelativeTo.Attachment0

		-- align orientation:
		align = Instance.new("AlignOrientation")
		align.Name = "align"
		align.Parent = att
		align.Mode = Enum.OrientationAlignmentMode.OneAttachment
		align.Attachment0 = att
		align.Responsiveness = 12

	else
		att = movePart:FindFirstChild("att")
		linear = att:FindFirstChild("linear")
		align = att:FindFirstChild("align")
	end	

	if not att or not linear or not align or not movePart or not cameraPart then return nil end	

	local function setAlignPosition(toggle)
		local function setPosition()
			alignLoop = runService.Heartbeat:Connect(function()
				align.CFrame = CFrame.new(movePart.Position, mouse.Hit.Position)
			end)
		end
		local function unPosition()
			if alignLoop then
				alignLoop:Disconnect()
			end
		end
		local func = toggle and setPosition or unPosition
		func()
	end

	local function setCameraCFrame(toggle)
		local function setCFrame()
			loop = runService.Heartbeat:Connect(function()
				tm.tween(camera, 1, {
					CFrame = cameraPart.CFrame
				})
			end)
		end
		local function unCFrame()
			if loop then
				loop:Disconnect()
			end
		end
		local func = toggle and setCFrame or unCFrame
		func()
	end

	local function setCenterCFrame(toggle)
		local function setCFrame()
			cframeloop = runService.Heartbeat:Connect(function()
				primaryPart.CFrame = movePart.CFrame
			end)
		end
		local function unCFrame()
			if cframeloop then
				cframeloop:Disconnect()
			end
		end
		local func = toggle and setCFrame or unCFrame
		func()
	end

	function functions.controlFire(keycode)
		if controlsUnlocked then
			local moveValue = findInTable(CONTROL_TABLE, keycode)
			if moveValue then
				if type(moveValue) == "vector" then
					moveValue = moveValue * movementMultiplier
					linear.VectorVelocity += moveValue
				end
			end
		end
	end

	function functions.controlHandoff(toggle)

		local function board()
			setCameraMode(true)
			setAlignPosition(true)
			setCenterCFrame(true)
			tm.tween(camera, 0.5, {CFrame = cameraPart.CFrame})
			setCameraCFrame(true)
			-- takeoff:
			linear.VectorVelocity = Vector3.new(0,20,0)
			task.wait(1)
			linear.VectorVelocity = Vector3.new(0,0,0)
			controlsUnlocked = true
		end
		local function exit()

		end
		local functionResult = toggle == true and board() or exit()
	end

	return functions
end

return module

MORE SPECIFICALLY:

function module.shipController()
	local functions = {}
	local ship = workspace.ships:FindFirstChild(plr.Name)

	if not ship then return nil end
	mouse.TargetFilter = ship
	local primaryPart = ship.PrimaryPart
	local cameraPart = ship:FindFirstChild("Camera")
	local movePart = ship:FindFirstChild("movePart")

	local controlsUnlocked = false
	local movementMultiplier = 20

	local cframeloop
	local alignLoop 
	local loop
	local att
	local linear
	local align


	workspace.Gravity = 0
	if not movePart then

		-- movepart doesnt exist:

		movePart = Instance.new("Part")
		movePart.Name = "movePart"
		movePart.Transparency = 0
		movePart.CanCollide = false
		movePart.Anchored = false
		movePart.Parent = ship
		movePart.CFrame = primaryPart.CFrame


		-- create att:
		att = Instance.new("Attachment")
		att.Name = 'att'
		att.Parent = movePart
		att.WorldCFrame = movePart.CFrame

		-- linear velocity
		linear = Instance.new("LinearVelocity")
		linear.Name = 'linear'
		linear.Parent = att
		linear.Attachment0 = att
		linear.MaxForce = 10000
		linear.RelativeTo = Enum.ActuatorRelativeTo.Attachment0

		-- align orientation:
		align = Instance.new("AlignOrientation")
		align.Name = "align"
		align.Parent = att
		align.Mode = Enum.OrientationAlignmentMode.OneAttachment
		align.Attachment0 = att
		align.Responsiveness = 12

	else
		att = movePart:FindFirstChild("att")
		linear = att:FindFirstChild("linear")
		align = att:FindFirstChild("align")
	end	

	if not att or not linear or not align or not movePart or not cameraPart then return nil end	

	local function setAlignPosition(toggle)
		local function setPosition()
			alignLoop = runService.Heartbeat:Connect(function()
				align.CFrame = CFrame.new(movePart.Position, mouse.Hit.Position)
			end)
		end
		local function unPosition()
			if alignLoop then
				alignLoop:Disconnect()
			end
		end
		local func = toggle and setPosition or unPosition
		func()
	end

	local function setCameraCFrame(toggle)
		local function setCFrame()
			loop = runService.Heartbeat:Connect(function()
				tm.tween(camera, 1, {
					CFrame = cameraPart.CFrame
				})
			end)
		end
		local function unCFrame()
			if loop then
				loop:Disconnect()
			end
		end
		local func = toggle and setCFrame or unCFrame
		func()
	end

	local function setCenterCFrame(toggle)
		local function setCFrame()
			cframeloop = runService.Heartbeat:Connect(function()
				primaryPart.CFrame = movePart.CFrame
			end)
		end
		local function unCFrame()
			if cframeloop then
				cframeloop:Disconnect()
			end
		end
		local func = toggle and setCFrame or unCFrame
		func()
	end

	function functions.controlFire(keycode)
		if controlsUnlocked then
			local moveValue = findInTable(CONTROL_TABLE, keycode)
			if moveValue then
				if type(moveValue) == "vector" then
					moveValue = moveValue * movementMultiplier
					linear.VectorVelocity += moveValue
				end
			end
		end
	end

	function functions.controlHandoff(toggle)

		local function board()
			setCameraMode(true)
			setAlignPosition(true)
			setCenterCFrame(true)
			tm.tween(camera, 0.5, {CFrame = cameraPart.CFrame})
			setCameraCFrame(true)
			-- takeoff:
			linear.VectorVelocity = Vector3.new(0,20,0)
			task.wait(1)
			linear.VectorVelocity = Vector3.new(0,0,0)
			controlsUnlocked = true
		end
		local function exit()

		end
		local functionResult = toggle == true and board() or exit()
	end

	return functions
end

EVERY WORKS FINE until I pass 1000 STUDS where the active properties of the velocity and constraint randomly go false. I have NO Idea why. Ive tried with both server and client ownership, where server ownership. works, but due to the gravity system of my game it is impossible for me to use the server for that. And I can’t make a force to counteract the gravitational force because I use a custom gravity solution. If there is ANY way I can fix this PLEASE TELL ME because honestly I would drink 2 gallons of coffee and have extreme constipation in severe pain then create a custom physics solution.

Video:

Thanks.

1 Like

Problem was caused by the ship leaving the players network distance

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