Get velocity between 2 parts for accurate collision

Im trying to make an accurate collision so that if a spaceship collided each other or collided something else and is very fast, it will blow up

So far i tried this :

local diffspeed = (script.Parent.AssemblyLinearVelocity.Magnitude - Part.AssemblyLinearVelocity.Magnitude)

if math.abs(diffspeed) >= 500 then
   print("blow up")
end

But i do realized that if the spaceship is facing the opposite way with what the spaceship is going to collide on and both the spaceship and what it’s gonna collide on has the same velocity, it wont print the “blow up” string

I do know that I need to include orientation for the diffspeed variable but I dont know how how to include it and what math is necessary. Thx

2 Likes

You should make a NumberValue inside your ships for Speed, and then just compare the two.

1 Like

but the problem is that if the ship is facing the opposite orientation with the thing its going to collide, and both got the same velocity, it wont blow up

1 Like

I don’t suppose you know how to get the FrontSurface of parts with a Script? I don’t know to do this myself, sorry for not helping much.

1 Like

To take into account orientation, it’s going to be difficult within Roblox as we don’t know the surface normal and point where the objects collide as there is no API for that Unity does though :frowning: . This is necessary for finding the impulse which is force multiplied by time.

Example google search:

image

Consequently, I’m going to make an assumption that the objects are spherical as the surface normal is easy to find from position of the objects

image

In order to find the momentum that is going to contribute towards the reaction force, vector projection will be utilized:

image
Where p1 = position, v1 = velocity, R1 is the surface normal.

Additionally, the smallest momentum will be given, ex the function will return R1 as momentum as that is the portion of the momentum that goes into collision and not translation movement.

image

--Projects vector a onto vector b, returns the magnitude
local function vectorProjectionAOntoBMagnitude(a : Vector3, b : Vector3)
    local numeratorTerm = a:Dot(b)
    local denominatorTerm = b:Dot(b)

    return numeratorTerm/denominatorTerm
end

local function findCollisionMomentum(part1 : BasePart, part2 : BasePart)
    local p1 = part1.Position
    local p2 = part2.Position
    local v1 = part1.AssemblyLinearVelocity
    local v2 = part2.AssemblyLinearVelocity
    local mass1 = part1:GetMass()
    local mass2 = part2:GetMass()

    local r1Direction = (p2-p1).Unit
    local r2Direction = -r1Direction

    local r1VelocityProjection = vectorProjectionAOntoBMagnitude(v1, r1Direction)
    local r2VelocityProjection = vectorProjectionAOntoBMagnitude(v2, r2Direction)

    --We only care about the + velocity going in the same direction as the reaction force, remove negative values
    --Also converts it into a momentum, because mass matters
    local r1NonZero = math.max(0, r1VelocityProjection)*mass1
    local r2NonZero = math.max(0, r2VelocityProjection)*mass2

    --Find the Minimum
    local netVelocityDifference = math.min(r1NonZero, r2NonZero)

    return netVelocityDifference
end
2 Likes

I see, its gonna be difficult with orientation

Also I just played with 2 parts for a few hours and just found a way to get the velocity between the 2 ships including when they are on a opposite orientation :


local part1 = game.Workspace.TestPartA
local part2 = game.Workspace.TestPartB

	
local v1 = part1.AssemblyLinearVelocity
local v2 = part2.AssemblyLinearVelocity
local diffspeed = (v1 - v2).Magnitude

print(diffspeed)


cheers!

2 Likes