Help with BodyVelocity

Hello! I need some help, yes you! I’m making a plane/helicopter thing (something that flies, okay?) and there is a problem: when I press the keyboard key W when touched my seat, it doesn’t go forward via bodyvelocity.
This is also my first time working with bodyvelocity so…
I made it so I have a local script and a normal script. The normal script has all the basic things such as seeing if a player touched the seat or etc, and the local script is where if you press a button, it moves.

---normal script beginning
local plane = script.Parent.Parent
local planeBody = plane.PlaneBody
local planeSeat = plane.VehicleSeat
local w = planeBody.LocalScript
w.Disabled = true
function onTouch(part)
	local character = part.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
	if player then
		local touchedSeat = planeSeat.Touched
		touchedSeat = true
		if touchedSeat == true then
			planeBody.Anchored = false
			planeSeat.Anchored = false
			w.Disabled = false
		else
			planeBody.Anchored = true
			planeSeat.Anchored = true
			w.Disabled = true
		end
	end
end
---start of local script, end of normal script
local BV = planeBody.BodyVelocity
local m = game.Players.LocalPlayer:GetMouse()
db = true
m.KeyDown:connect(function(k)
	k = k:lower()
	if k == "w" then
		if db == true then
			BV.Velocity = Vector3.new(10, 0, 0)
		end
	end
end)

Is there anything wrong?
Thanks a lot!

3 Likes

The reason why it doesn’t go forward is that you’re making it go forward on the X-axis, not by the plane’s look vector, in other words, the position the plane is facing.

To resolve this, basically, just get the lookVector either the planeBody or planeSeat and multiply it by the preferable speed, I prefer getting the seat’s look vector.

Basically, replace

BV.Velocity = Vector3.new(10, 0, 0)

with

BV.Velocity = planeSeat.LookVector * 10 

If it’s not going forward, it’s because of the seat it’s facing, you can fix that by rotating it on studio to the front of the plane.

1 Like

Thanks very much! I will try that.

@Crictoli, I tried that but it isn’t working.

local m = game.Players.LocalPlayer:GetMouse()
local BV = script.Parent.BodyVelocity
local planeSeat = script.Parent.Parent.VehicleSeat
db = true
m.KeyDown:connect(function(k)
	k = k:lower()
	if k == "w" then
		if db == true then
			BV.Velocity = planeSeat.LookVector * 10
			db = false
			wait(0.1)
			db = true
		end
	end
end)

This is the code.
Edit: wait I think I put the speed to 0, 0, 0.
Edit Edit: no that wasn’t the problem

Are there any errors? If no then, I believe it’s the debounce. Instead of using debounce, use KeyUp to stop its velocity.

Since using KeyUp and KeyDown are deprecated, I recommend using UserInputService.

(Currently making a code with explanation if you want me to)

1 Like

So… I would do:

m.KeyUp:connect(function(k)

Is that correct?
Oh, and I would like to see the code when your finished, so I can learn.
Edit: I mean change it from m.KeyDown to m.KeyUp, right?

Yes, you can use m.KeyUp.

Anyway, I don’t think debounce is an error, the reason why it doesn’t work is because of the parent of the Localscript, I recommend you parent the plane to the character and set the plane back on workspace or clone the localscript and parent on the playergui, backpack, or the character and destroy once you get out out of the plane.

And yes, I still recommend using UIS.

A simple explanation:

  • Basically, InputBegan is KeyDown, and InputEnded is KeyUp
  • The input is a user input (from keyboards, mobile devices, mouses, etc.)
  • The abbreviation of gmp is Game processed, it is a boolean which indicates if the input is interacting with the game engine.
local uis = game:GetService("UserInputService")
local plane = script.Parent.Parent
local planeBody = plane.PlaneBody
local planeSeat = plane.VehicleSeat
local BV = planeBody.BodyVelocity
local m = game.Players.LocalPlayer:GetMouse()

uis.InputBegan:Connect(function(input,gmp) 
	if gmp then return end 
	
	if input.KeyCode == Enum.KeyCode.W then		
		BV.Velocity = planeSeat.CFrame.LookVector * 10 
	end
end)

uis.InputEnded:Connect(function(input,gmp)
	if input.KeyCode == Enum.KeyCode.W then
		BV.Velocity = Vector3.new(0,0,0)
	end
end)
2 Likes

Okay, I’ll copy this code and I’ll review it in studio. Thank you so much!
Edit: I didn’t mean copy.
i always think to copy something…

@Crictoli, there is something wrong. I have a error where it says:image
This is the code:

local m = game.Players.LocalPlayer:GetMouse()
local BV = workspace.Model.PlaneBody.BodyVelocity
local planeSeat = workspace.Model.VehicleSeat
local LookVector1 = planeSeat.CFrame.LookVector
function onTouch(part)
	local character = part.Parent
	local player = game.Players:GetPlayerFromCharacter(character)
	local org = script
	local soonParent = org:Clone()
	soonParent.Parent = character
	if player then
		local touchedSeat = planeSeat.Touched
		touchedSeat = true
	else
		soonParent:Destroy()
	end
end
db = true
m.KeyUp:connect(function(k)
	k = k:lower()
	if k == "w" then
		if db == true then
			BV.Velocity = planeSeat.LookVector * 10
			db = false
			wait(0.1)
			db = true
		end
	end
end)

What is wrong? And can you possibly find it? Thank you.

BV.Velocity = planeSeat.CFrame.LookVector * 10

1 Like

Thank you very much, I wouldn’t have guessed that.

Lol my bad, I forgot to add CFrame there.

It’s fine, I thought there wasn’t supposed to be CFrame despite me not knowing it was supposed to be there.
Edit: How would I make it go in the standard WASD movement because all I know is the W movement… is it the same with the ASD?

I’ve been working on my code for so long, it feels like a couple of hours, and it possibly could’ve been.
I decided to try and add a shooting system to the plane… and it isn’t working. Of course.

local f = game.Players.LocalPlayer:GetMouse()
local sound = workspace.Model.Guns
local planeTip = workspace.Model.Tips:GetChildren()
db = true
wait(10)
f.KeyUp:connect(function(k)
	k = k:lower()
	if k == "f" then
		if db == true then
			sound.Playing = true
			local bullet = Instance.new("Part", workspace)
			bullet.Name = "Bullet"
			bullet.Material = "Neon"
			bullet.Color = Color3.new(229, 222, 0)
			bullet.Transparency = 0
			bullet.CanCollide = false
			bullet.Locked = true
			bullet.Position = Vector3(planeTip.Position)
			--bullet.CFrame = CFrame.new(planeTip.CFrame)
			db = false
			wait(0.1)
			db = true
		end
	end
end)

I need your help again, and your advice @Crictoli, and I’m sorry to bother you but your the only one who really understands these things and kind of is teaching me so… can you help? Thanks!

What is the parent of that script and what type of script is that?

Also If it’s executed by a localscript, the other clients and server can’t see and hear it, so I recommend detecting input from a localscript, and making a bullet and playing the sound.

Parent of the script is StarterPlayerScripts and it is a local script. Am I supposed to change it to a normal script?

Small suggestion: you could a customised velocity script that can be adjusted to your liking as a module that can be required!

Not everything is supposed to be modified into a script. The input will be the only thing that’s left unedited. To play sounds and make bullets for others to see it, detect input from the client and use a RemoteEvent for communicating from client to server, which playing sounds and making the bullet will be handled in the server.

Okay…
This is the normal script. Edit: AND the local script.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
local f = game.Players.LocalPlayer:GetMouse()
local sound = workspace.Model.Guns
local planeTip = workspace.Model.Tips:GetChildren()
db = true
wait(10)
local function onCreateNewBullet()
	f.KeyUp:connect(function(k)
		k = k:lower()
		if k == "f" then
			if db == true then
				sound.Playing = true
				local bullet = Instance.new("Part", workspace)
				bullet.Name = "Bullet"
				bullet.Material = "Neon"
				bullet.Color = Color3.new(229, 222, 0)
				bullet.Transparency = 0
				bullet.CanCollide = false
				bullet.Locked = true
				bullet.Position = Vector3(planeTip.Position)
				--bullet.CFrame = CFrame.new(planeTip.CFrame)
				db = false
				wait(0.1)
				db = true
			end
		end
	end)
end
remoteEvent.OnServerEvent:Connect(onCreateNewBullet)
--this is the local script
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")

remoteEvent:FireServer()

I don’t understand remote events.

Like I previously mentioned, the input and the FireServer function is supposed to be handled in a localscript, and creating the bullet and playing the sound is handled in the OnServerEvent function.

Remote events are the most used way for communicating and is being created for the purpose of sending a message between the server and the client.

For example, if you want to communicate from a client to the server, it can be done by using the FireServer function and adding data by adding it as a parameter

(RemoteEvent):FireServer("data",1,Vector3.new())

When a client calls the function, any functions on the server that are connected to OnServerEvent will fire. Note that the player object or the caller will always be the first parameter.

(RemoteEvent).OnServerEvent:Connect(function(plr,data,number,vector)
    -- code
end

To learn more, you can go to this link: Bindable Events and Functions | Roblox Creator Documentation.

At this point on if you need help, just create a new post or message me.

1 Like