Moving a part of variable size

Hi, my problem is to do with scripting a moving part for a magic spell.

So basically, when a player casts a spell I can a script which fades in a part for the spell, more specifically a dragon head, then add a force to fire it towards the mouse.Hit. The part’s size varies, it is calculated using this code:
local size = Vector3.new(0.96, 0.84, 1.68) + Vector3.new(5.76, 5.04, 10.08) * multiplier
part.Size = size
multiplier is the level of the player’s spell, as a fraction of the maximum level for the spell, therefore it always falls between zero and one. Where multiplier = 0, the part is about the size of the character’s head. Where multiplier = 1, the part is roughly 90% the height of the character, and the width/length grow proportionally.

Problem is, I have no clue how to vary the force applied so that the part travels at the same speed regardless of size/mass, which is what I’m trying to achieve. I have had no problem with direction, just not enough force being applied or way, way too much.

So far, I’ve extensively tried BodyVelocity, BodyPosition and BodyForce. BodyVelocity wouldn’t work when the part was large, even if I multiplied the velocity by math.Huge. BodyPosition would move in a weird manner, I guess I just don’t know how to use it. And with BodyForce, I just can’t get my numbers right. I’ve had the part set to massless, doesn’t seem to change anything.

Using BodyForce, I’ve tried using exponentials, for example:
BodyForce.Force = part..CFrame.LookVector*500 + part.CFrame.LookVector*part.Mass^3,
which works well for the heavier parts, but absolutely flops for the smaller parts.
I’ve tried using a base plus an exponential, for example:
BodyForce.Force = part.CFrame.LookVector*500 + part.CFrame.LookVector*part.Mass^3,
but again, it just doesn’t keep the speed constant for all size values.

For extra information: the part’s mass ranges from 0.91 to 205. To describe the speed I want the part to travel at, I’m going for a speed where you can see it coming, but its pretty hard to dodge and impossible to keep up with. Sorry if that’s too vague, I can work out the speed I’m going for if needed.

Should I resign from using BodyMovers and just tween the part? Thus far I’ve avoided doing that, because I want the part to have a very natural and constant motion. I’m at a loss right now, any input is appreciated, thanks for reading all that.

1 Like

LookVector is a property of CFrame, not BaseParts, use part.CFrame.LookVector

That’s a typo, it’s not like that in my script. My bad, I’ll change the post to reflect that

You could do something like this

local start	= tick()
local acceleration = force / mass -- both are numbers
local duration = 5
repeat
	Part.Velocity = Part.CFrame.LookVector * acceleration
	RunService.Stepped:wait()
until tick() - start > duration 

it is not the best way to solve this issue, but it certainly helps out with the unconsistancy issues

2 Likes

:wait() is deprecated use :Wait()
Also I suggest you use os.clock() instead of tick() as it has more percision.

Also .Velocity is being deprecated so the new thing is BasePart:ApplyImpulse()

2 Likes

So you basically want to normalize or in a sense make its velocity vector of length 1 while also maintaining direction and use that as the base line for our scalar. The scalar is how fast we want the player to be going. So if we want to apply a body force with a constant speed, almost like body velocity we need to redact the forces of gravity. that being our gravitys scalar workspace.Gravity and the total mass of the collection of parts or just part:GetMass() multiply those two together. Now any other value you add to this now will be how much it travels a second. So if you want to move it in the look vector 5 studs on the z a second we do

part.BodyForce = (workspace.Gravity * part:GetMass()) * part.CFrame.LookVector * 5 --Note that we don't need to normalize look vector as it is already a normalized value, no need to call .Unit on it
3 Likes

This seems to not work. I put a print statement within the repeat loop, so that code is definitely being run and without error. Maybe directly setting the velocity doesn’t actually move the part, I dunno lmao

have you tried my code :smirk: :point_right: :point_left:

1 Like

What are the force and mass values you use? You might need to tweak them a bit to make acceleration at the very least a hundred or around that

1 Like

Sorry if it seems like I’m ignoring you lol. Firstly thank you for the explanation, I don’t know why gravity didn’t cross my mind once this entire time, as if the part is in space or something. Right now I’m trying to get your code to work with my script:

local function move(part, velocity, power)
	local force = Instance.new("BodyForce")
	part.Anchored = false
	force.Name = "Force"
	force.Force = velocity + (workspace.Gravity * part:GetMass())
	--force.P = power
	force.Parent = part
	print("Force added!")
end

move(mesh, mesh.CFrame.LookVector*5)

The power stuff is dashed out, I was playing with it earlier but to no avail.

Right now I’m getting an error: Workspace.Eli_Melekh.Folder.LocalScript.ClientBattleModule:70: invalid argument #2 (Vector3 expected, got number), on the line that I used your code, I’m guessing gravity’s work is supposed to come out as a 3d vector? Again idk lmao

change the + to a * and tell me what you get

2 Likes

I used 500 for force. For mass, I set part.Mass which ranges from 0.91 to 205, the part was big at the time so I estimate around 190 for mass.

Brilliant! The only thing now is that it seems that the code fights against gravity alright, but it’s evident that gravity is still causing the projectile to go off target, as each time I fire it it goes in the correct direction, but about 20 degrees downwards, rotating in the x-axis. Any idea how to fix that?

The consistency is perfect, it keeps a constant speed across all masses, thankssssssss

1 Like

maybe get rid of gravity locally for that part? i am not sure tbh

You could also try multiplying it by the delta time

1 Like

Update: I’ve decided to just tween the parts, it’s just more convenient, I guess. Thanks everyone for your help, especially Husk :smiley:

In your response that I marked as the answer please could you change the + to * for anyone who sees and tries to use it

1 Like