I can't get BodyVelocity I added to the player to be removed when they stop touching a part after a few seconds

I want to make it so when the player stops touching a part after a few seconds a new value of BodyVelocity gets destroyed.
I don’t really know how to do it but I tried making a new value but that didn’t work. I tried putting newvalue:Destroy but that didn’t work either.
Somebody gave me an original script and I have kept making edits to it as time goes on and I need to do other things with the script. The first function works but the second one doesn’t. In one of the edits instead of using TouchEnded it used OnHeartBeat I think but that didn’t work either.
This is the script:

local part = script.Parent-- Get the part that the player will touch
local RunService = game:GetService("RunService")
local newvalue = Instance.new("BodyVelocity")

part.Touched:Connect(function(otherpart) -- Connect to the part's touched event
	local hrp = otherpart.Parent:FindFirstChild("HumanoidRootPart") -- Find the player's HumanoidRootPart

	local bodyvelocity = hrp:FindFirstChildWhichIsA("BodyVelocity")	-- Check if the player has a body velocity attached
	if hrp and not bodyvelocity then
		newvalue.Velocity = Vector3.new(0, -25, 0) -- give an upward velocity of 10000 in the Y-axis
		newvalue.MaxForce = Vector3.new(10000, 10000, 10000) -- Set the max force to be able to apply to the player's humanoid rootpart
		newvalue.P = 5000 -- Set the damping property of the body velocity to 5000
		newvalue.Parent = hrp -- Parent the body velocity to the player's humanoid root part
	end
end)

part.TouchEnded:Connect(function(otherpart)
	local hrp = otherpart.Parent:FindFirstChild("HumanoidRootPart")
	
	local bodyvelocity = hrp:FindFirstChildWhichIsA("BodyVelocity")
	if hrp and not bodyvelocity then
		task.wait(5)
		newvalue:Destroy()
	end
end)

My Random Speech (Not related to this)

Sometimes I rely on the developer forum in order to figure this stuff out. I always try to not ask people for straight up scripts and do my best to write a script before asking for help, however even then I have ended up having to ask people for a script because sometimes they will say to do this and that and then do this and I don’t even understand what they mean. The other times are when I have a script that has a major error in it which I do try to minimize if I can. I just don’t want to ask people for entire scripts or systems like the developer forum says because I want to at least do something and not have other people make an entire game for me. I’m trying to get better at certain things when making games but I have such little time to do things sometimes that I can barely put in time to learn any of that stuff. I usually only find tutorials when I need to find out something in the exact moment (Which has happened a lot with my other game which is way more advanced compared to what I have experience doing). I guess I’m kind of a casual style game developer. I don’t make games for a living, but I also want to make games that are at least decent. My best one would be Hypnagogia which is a 2D game that I have paused working on. It requires more advanced things and scripts that I am trying to do. It has only a small amount of gameplay in it because each part of it takes so long to make. I made cutscenes without movement though which is better than what I have made in the past. If you want an idea of what the game is like I made it to be similar to the game “A Lucid Dream”. You may also be able to find what the game looks like in my old topics about it. I hope to release it sometime within the next few years but it depends on how much time and effort I put into it. I want to make a moon follow the player and then when the player reaches a certain part the moon becomes the sun but I don’t even know how to make a part follow the player. I might be able to figure out how to make it transform using an event where one part touches another part but it would take a lot of figuring out. Anyways that was my long speech about whatever came to mind. Thanks for reading it :upside_down_face:.

1 Like

It’d only work once because you’ve only defined newvalue with Instance.new("BodyVelocity") once.
Anyways, were there any errors? Have you tried creating the new instance inside of the first function? You can define empty variables as nil, or not assign a value at all.

1 Like

In the original script Instance.new("BodyVelocity") was inside the first function but I was worried that if it was kept like that the second function would not know what newvalue was. I did notice an error just now that says Workspace.Dropper.Slowdown.Script:20: attempt to index nil with `FindFirstChildWhichIsA`
Also I would want this to work more than once.

1 Like

It looks like it’s touching other parts that don’t have a HumanoidRootPart. You should add a null check for that:
if not hrp then return end

1 Like

This is what you need, Enjoy !

local Part = script.Parent

local function CreateBodyVel(Root)
	local BodyVel = Instance.new("BodyVelocity", Root)
	BodyVel.Velocity = Vector3.new(0, -25, 0)
	BodyVel.MaxForce = Vector3.new(10000, 10000, 10000)
	BodyVel.P = 5000
end

local function CheckBodyVel(Hit)
	local Root = Hit.Parent:FindFirstChild("HumanoidRootPart")	
	if Root and not Root:FindFirstChildWhichIsA("BodyVelocity")then
		CreateBodyVel(Root)
	elseif Root and Root:FindFirstChildWhichIsA("BodyVelocity")then
		Root:FindFirstChildWhichIsA("BodyVelocity"):Destroy()
	end
end

Part.Touched:Connect(CheckBodyVel)
Part.TouchEnded:Connect(CheckBodyVel)
2 Likes

That does exactly what I’m looking for. All I needed to do was add task.wait(5) to it and it does what I’m looking for. Thanks for the help. (Thanks for the help too @TestyLike3). Now all I need to do is figure out how to make it so the player’s y velocity is set to 0 for a split second when they touch the part. Currently my patch for that is to anchor the entire player for 1 second so that way the slow down actually works but when I do that the player flings all over the place. I might be able to figure out how to do it by using the current script. Maybe if I were to make it so when the part is touched the y velocity is set to 0 for a split second but I’m not entirely sure how to do that. I might be able to figure it out but I might not be able to, and if that’s the case then I will make another topic.

2 Likes

Alright, so it should be something like this if i good understand.

local Part = script.Parent

local function CreateBodyVel(Root, Hum)
	local CurrentSpeed = Hum.WalkSpeed	
	Root.Anchored = true
	Hum.WalkSpeed = 0
	task.wait(0.25)
	Root.Anchored = false
	Hum.WalkSpeed = CurrentSpeed
	local BodyVel = Instance.new("BodyVelocity", Root)
	BodyVel.Velocity = Vector3.new(0, -25, 0)
	BodyVel.MaxForce = Vector3.new(10000, 10000, 10000)
	BodyVel.P = 5000
end

local function CheckBodyVel(Hit, State)	
	local Root = Hit.Parent:FindFirstChild("HumanoidRootPart")	
	local Hum = Hit.Parent:FindFirstChild("Humanoid")
	
	if Root and Hum and not Root:FindFirstChildWhichIsA("BodyVelocity") and State then
		task.spawn(CreateBodyVel, Root, Hum)
	elseif Root and Hum and Root:FindFirstChildWhichIsA("BodyVelocity") and not State then
		Root:FindFirstChildWhichIsA("BodyVelocity"):Destroy()
	end
end

Part.Touched:Connect(function(Hit)
	CheckBodyVel(Hit, true)
end)

Part.TouchEnded:Connect(function(Hit)
	CheckBodyVel(Hit, false)
end)

I ended up messing around with some stuff and I could not get it to work. When this script anchors the player and then un-anchors them the player flings around mid air. Also the new Velocity isn’t removed after a certain amount of time. I tried creating another part 10 studs above the original part with this script:

local Part = script.Parent

local function CreateBodyVel(Root)
	local BodyVel = Instance.new("BodyVelocity", Root)
	BodyVel.Velocity = Vector3.new(0, 0, 0)
	BodyVel.MaxForce = Vector3.new(0, 0, 0)
	BodyVel.P = 100000
	BodyVel.Parent = Root
end

local function CheckBodyVel(Hit)
	local Root = Hit.Parent:FindFirstChild("HumanoidRootPart")	
	if Root and not Root:FindFirstChildWhichIsA("BodyVelocity")then
		CreateBodyVel(Root)
	elseif Root and Root:FindFirstChildWhichIsA("BodyVelocity")then
		task.wait(5)
		Root:FindFirstChildWhichIsA("BodyVelocity"):Destroy()
	end
end

Part.Touched:Connect(CheckBodyVel)
Part.TouchEnded:Connect(CheckBodyVel)

The problem with that is that it wouldn’t stop the player like anchoring the player does but if I anchor the player they start to fling all over the place when they are un-anchored. I figured if I changed the velocity of the player when they are anchored to be nothing in all directions then the player wouldn’t fling all over the place but they still did.

I’m going to make a new topic about this now.

BodyVelocity should not even be used for newer work. It is deprecated and LinearVelocity should be used instead.

1 Like

I’ll make sure to take note of that for future reference. Somebody told me the same thing except with wait() and task.wait().

For anybody who wants to help me with my other issue you can find it in this post.

With wait(), it’s not the fact that it is deprecated. It isn’t at all. task.wait() is better because it is more consistent with time. It actually runs for that amount of time instead of running every 1/30 of a second. task.wait() works similar to FixedUpdate in Unity.

Well you get the idea, task.wait() is better to use compared to wait. The times that task.wait() matters the most is when you need small measurements of time (at least I think so), like when moving a part. I do wish there was a better way of moving a part without it looking bad, especially if somebody has to move that part a long distance in a shorter amount of time. If that happens then the part won’t look so good moving across.

What do you mean by “looking bad”? Kinda confused, so pardon me please.

And please DM me here with what you mean so neither of us get in trouble for being off-topic.

1 Like