Replicating BodyVelocity using constraints

Hey,

After doing some research, I found there was no equivalent for BodyVelocity in the newer constraints system. The idea is that BodyVelocity would apply force to something until the velocity of that thing became the same as the velocity you set. I’m not sure how exactly that works under the hood, so is it possible to replicate that with constraints (e.g. VectorForce) and if so, what maths will I need to use to calculate the force to apply?

2 Likes

BodyVelocities have a Velocity property, which is a Vector3 value. Once it achieves its target velocity, it will continue going on this velocity forever (unless something is in its way) or if you change the Velocity property. Is this the behavior you want? I believe you want something else due to what you said here.

What the BodyVelocity object does is it continues on that velocity even after it is achieved. If it stopped, it would simply stay there and or fall from gravity (if moving on the Y axis).

1 Like

Thanks for the quick response, but I already know about BodyVelocities; I’m actually asking for a way to recreate the behaviour of BodyVelocity using the newer constraints system :slightly_smiling_face:

1 Like

I understand, so you want it to continue forever if you give it a Velocity property of say (40,0,0), but with constraints? How would you describe this with constraints? Would you be using wheels? How would a constraint object replicate the behavior of a BodyVelocity body mover? Sorry for being confused.

1 Like

Suppose I have a VectorForce acting on a part, which applies a force relative to the world on the part. Is there a way to manipulate that VectorForce in a way that matches the behaviour of a BodyVelocity, to make the part move at some constant velocity relative to the world?

This is my first time seeing the VectorForce constraint object but just by looking at the properties tab, I see a property named “Force”. Try modifying that. Does it slow down, though? I haven’t tested it, and I don’t want to build a rig to test it at the moment.

Yea I already know what the Force property does - my question is how can I calculate that force so that the part moves at a constant velocity?

If the VectorForce object doesn’t do it for you, it’s not possible to calculate a force that changes that is constant. That thinking is paradoxical. If that confuses you, let me give an example.

Say that you set the velocity to 50, but it slows down, there isn’t a “magic number” that makes something stay a constant velocity.

There is a band-aid fix for this. You can use a while true do loop to continuously set the velocity to something to keep it relatively constant. I say relatively because there is a time it will slow down before it is set by the code in the loop again.

I’m aware of this already, I just need some calculation I can perform to get the force to use in the VectorForce, based on the velocity of the part and any other factors required :confused:

Oh! Parts have a property known as “Velocity”, which is a Vector3 value. Add each constructor of part.Velocity to each constructor of your extra force.

Example:

newVelocity = Vector3.new(Part.Velocity.x+extraForce.Velocity.x,Part.Velocity.y+extraForce.Velocity.y,Part.Velocity.z+extraForce.Velocity.z)

What that will do is it will add the current velocity of a part to the velocity to want to add to get a new velocity you can set whatever you want to, i.e. a VectorForce!

Didn’t appear to work :frowning:
Left; BodyVelocity
Right; VectorForce

Code (based on your suggestion):

local Part = script.Parent

local TargetVelocity = Vector3.new(2, 2, 2)

while wait() do
	Part.VectorForce.Force = Part.Velocity + TargetVelocity
end

Setup:
image

Try sticking the VectorForce in another object, I’m playing with them in studio, and I put mine in Baseplate.

Edit: Try putting the force in the direction you want higher as well.

Moving it into another object wouldn’t help, since we’re trying to apply the force to the part so that its velocity is the target velocity :confused:

Also increasing the magnitude of the force doesn’t work either, so yea

Try this code and set the Attachment0 property to an attachment that is inside of the part you want to move:

local Part = script.Parent

local TargetVelocity = Vector3.new(500, 0, 500)

Part.VectorForce.Force = Part.Velocity + TargetVelocity

Edit: Keep in mind you can set those values in the Vector3 to your liking, but if it doesn’t move set it to something high(er).

Don’t use constraints unless you need too, they are the main source of physics lag.
I don’t know if you can replicate the effect with constraints though.

However, if you don’t wanna do BodyVelocity, you can use scripting alone. It will be more efficient to do this with a low part count.

You can make the part move on every RunService.RenderStepped or RunService.Heartbeat. I recommend Heartbeat in order to keep a consistent movement without possible lag. Using only scripts, you can also move it from client or server (use server w/ heartbeat if you are trying to get everybody to see it, use client for singleplayer games or uncommon circumstances).

Here is a sample code I have not tested. This is very simple, but it works actually better with Anchored parts.
local velocity = Vector3.New(0,10,0) -- Velocity in XYZ format
local part = workspace.PartNameHere -- The part moved
local Heartbeat = game:GetService("RunService").Heartbeat -- The Heartbeat Event
local damping = Heartbeat:Wait()

Heartbeat:Connect(function()
-- Your movement code goes here. Lemme know if you need this part.
end)

If this confuses you or does not help, give me a shout. Hope it makes some sense.

1 Like

The TargetVelocity.Y should be able to combat the gravity (with whatever number that works) in order to replicate the BodyVelocity Effect. If you want it to move up, do the “gravity combat” plus whatever velocity

I agree with @iGottic. I dislike using constraints unless it’s in a car or something that would use constraints, but not for moving a part.

The part is just an example. I would like to use constraints. I cannot use Anchored parts because this code will be part of a larger physics-driven system, and I would rather avoid using body movers as they’re considered legacy objects and shouldn’t be used in newer projects. Nothing thus far has answered my question :confused:

Aight, good to know.
So overall, don’t use constraints. I have made multiple ragdoll games and collaborated with other ragdoll makers such as @paratype, and I can see that constraints are best used for effects. I also agree with @chasedig1 with using them for cars, as long you can control “Snapping”.

Use BodyVelocity if you want, because it’s not too bad. Even though it is considered a legacy object, it can get the job done fairly efficiently.
You can also manually set the velocity of a part using the Velocity property of the part. @chasedig1 gave a decent example of that.

What kind of game are you making to introduce a scenario like this? I could help more if I knew.

Edit: Do know that physics of any kind greatly impacts the performance of your game. Avoid it if you game does not need it.

3 Likes

I’ve so far made some progress on this problem independently:

local RunService = game:GetService("RunService")
local Part = script.Parent

local TargetVelocity = Vector3.new(2, 2, 2)

local function UpdateForce()
	Part.VectorForce.Force = (Vector3.new(0, workspace.Gravity, 0) + (TargetVelocity - Part.Velocity)) * Part:GetMass()
end

UpdateForce()
RunService.Heartbeat:Connect(UpdateForce)

The code almost works as expected:
export2

As you can see, the part’s velocity does eventually match the velocity of the part on the left, but there appears to still be a small acceleration period at the start of the process. Is there any way of minimising or eliminating this acceleration period?

edit: nevermind, figured it out on my own, I just set the part’s Velocity to the target velocity directly at the start.

3 Likes