Predict where a part will be and "intercept" it

  1. What do you want to achieve?
    I am attempting to make a Part (Part1), predict where another Part (Part2) will be, and “intercept” it with minimal direction adjustments, as in, I want Part1 to predict where Part2 will be and point at that position whilst also constantly updating the intercept position if Part1 changes its direction.

  2. What is the issue?
    I am having a hard time with the actual maths. I’ve gotten Part1 to successfully point at Part2, but I am not sure where to start with the interception maths.

-- this obviously wont predict anything
Primary.AlignOrientation.CFrame = CFrame.new(Primary.Position, workspace.Projecticle.Position)
  1. What solutions have you tried so far?
    I have attempted to calculate the part’s linear velocity
function getDirection(from, to)
    local fromPos = from.Position;
    local toPos = to.Position;
    
    local direction = toPos - fromPos;
    toPos = toPos + to.AssemblyLinearVelocity;
    direction = toPos - fromPos;
    
    return direction;
end

-- lower in the script:

local direction = getDirection(Primary, workspace.Projecticle)
Primary.AlignOrientation.CFrame = CFrame.new(Primary.Position, direction * direction.Magnitude)

As you can see I am not great at maths haha.

So, how would I predict where the target part will be, and make the interceptor part point at it?
What maths is involved?
If you need more information about a specific point let me know!

1 Like

What do you mean by predict? Do you mean that you are able to point in a direction X steps ahead of the projectile? Or do you mean something like this (which follows the reasoning of your first part):

For something other than this you’d need to specify how far in advance you want to predict. Realistically any accurate prediction would also need the logic used to move a projectile.

1 Like

Hey there,
As for predict I mean something like this:


I want the interceptor part to predict where the target part will be, and align itself to point at the intercept position*

  • Aligning itself isn’t the issue here, I just don’t know how to “predict” where the target part will be with maths.
  • Assume the logic regarding thrust/movement is already taken care of

Ive never made anything that can predict where an object will be in the future before.

However to start off you would need the direction, velocity/speed, and time it takes the object to move from one position to another (example in 1 second it moved 10 studs)

Once you have all of these values im sure you can start making something

(Again if you know it takes an object 1 second to move 10 studs, you can predict that in 10 seconds the object will be 100 studs from its original position)

I would need the code for the movement of the projectile. If it’s linear, then it’s more straightforward.

1 Like

To evaluate the prediction, you need to understand how the object moves: uniformly rectilinearly, rectilinearly uniformly accelerated, uniformly along a given curve trajectory. All this is described using physical formulas from kinematics and mathematical analysis of functions.
What do you know for a moving body: speed (initial, final), acceleration, force (on which axis, modulus), material (mass - here is an experimental approach). Maybe you have an equation of the function on the graph of which this body moves?

For example, you have the start and end points of the movement, therefore, you know the path (distance) traveled. If it moves uniformly, then you can first determine the time of movement, and then based on this its speed. After that, s = V*t. This is the definition of a path for a certain period of time. After that, we multiply this element by the unit displacement vector and get the coordinates of the exact position for a given time interval.

1 Like

The code for the movement is a VectorForce named thrust being tweened to it’s max speed

TweenService:Create(Primary.Thrust, TweenInfo.new(Stats.timeToReachMaxSpeed), {Force = Vector3.new(0,0,-speed)}):Play()

Once it reaches it’s max thrust, it stays at that thrust as the Thrust VectorForce is never disabled.

However there is another VectorForce applying drag like so:

if Primary.AssemblyLinearVelocity.Magnitude > 0 then
  local dragVector = -Primary.AssemblyLinearVelocity.Unit;
  local v2 = Primary.AssemblyLinearVelocity.Magnitude ^ 2; -- i usually set this to 1.2

  Primary.VectorForce.Force += dragVector * drag * Primary.AssemblyMass * v2;
-- note that 'drag' is usually 0.5
end

Are you using a physics equation for the drag portion? If not, will it be constant or changing?

The initial speed change and base velocity should be pretty easy to predict, but if the drag is more variable this may be marginally more tricky.

1 Like

the drag is calculated inside a RunService.Heartbeat event and updates itself accordingly with the code above

It mostly changes depending on AssemblyLinearVelocity and AssemblyMass does not change

Sorry for the late reply.

I’ll give you a quick outline of the math involved plus some pseudocode to show basic implementation and then give something more solid if you need it when I have more time.

You need to find the velocity of an object accelerating linearly in the future (a time t more than the current clock). This is arbitrarily defined by you, but in order to find distance moved you need to establish a velocity time function. Gradient is dy/dx, in this case dv/dt. Since both velocity and time begin at 0, this simplifies to m = max_v/max_t. i.e The end velocity in the z direction (or whichever) divided by timeToReachMaxSpeed. So:

v = m*t

Once you have the equation you need to find the change in distance. You can either integrate with limits, or use this (probably simpler, but limited to linear/trapezoidal graphs) method:

0.5*(t2 - t1)*(v1+v2)

This all comes together as something like:

max_t = TIME_TO_REACH_MAX_SPEED
max_v = MAXIMUM_VELOCITY
m = max_v/max_t

while (wait(max_t - increment)) do
-- not sure if this is the correct pathway to current velocity or not
  v1 = object.AssemblyLinearVelocity 
  t1 = v1/m
  t2 = t1 + increment
  v2 = m*t2
  d = 0.5*(t2-t1)*(v2+v1)
  vec = Vector3.new(original.X, original.Y, original.Z + d)
  pointingObject.CFrame = CFrame.new(pointingObject.Position, vec)
end

You could use something like this in conjunction with the tween. I haven’t applied the drag here, but you could easily do so by passing the respective values of velocity into a dragApply() function and then use the return value for the distance formula instead. After the tween you can just multiply the maximum velocity by time increments to get distance, and then add change in distance to current position (and then point the pointObject at that position).

N.B this will only work for a linear change in velocity in a single direction, though it wouldn’t be difficult to add multiple dimensions (x,y) changes also.

2 Likes

wait() is deprecated, use task.wait() instead.
It is more performant and works with the lua task scheduler making it more reliable.

1 Like

Thank you! Much appreciated and thank you for your help! :smile:

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