I’m trying to trace the movement of a part. What I would like to achieve is similar to a bullet tracer, but persistent, starting from where the part is when I call ApplyImpulse
on it. It would be great to have the tracer 3D in some way (not like a Beam or a Trail that is a flat plane). The part has custom physical properties and the workspace has custom gravity, not sure if that’s important.
I’m trying to achieve the same effect as golf shot tracers. this is a golf game
Right now I have a system that approximately shows the path the part is expected to take when I apply the force, but because of the custom physical properties (I think) the path isn’t exact, so I have to divide by a really precise number to get an approximate result.
How do I show path of projectile? - Help and Feedback / Scripting Support - Developer Forum | Roblox
Code for the calculated full path
Applying the force
local velocity = Vector3.new(0, clubData[club].HeightVelocity, clubData[club].DistanceVelocity)
ball:ApplyImpulse(velocity)
local gravity = Vector3.new(0, -workspace.Gravity, 0)
createAndSetBeam(gravity, velocity / 4.483, ball.Position, 8) -- I have to divide by 4.483 to get a close enough path to accommodate for the physical properties
Calculating path
local function createBeamInProjectileMotionPath()
local attach0 = Instance.new("Attachment")
local attach1 = Instance.new("Attachment")
local beam = Instance.new("Beam")
beam.Color = ColorSequence.new(Color3.new(1, 0.035294, 0.035294))
beam.Attachment0 = attach0
beam.Attachment1 = attach1
beam.Parent = workspace.Terrain
attach1.Parent = workspace.Terrain
attach0.Parent = workspace.Terrain
return beam, attach0, attach1
end
local function beamProjectile(g, v0, x0, t1)
-- calculate the bezier points
local c = 0.5 * 0.5 * 0.5
local p3 = 0.5 * g * t1 * t1 + v0 * t1 + x0
local p2 = p3 - (g * t1 * t1 + v0 * t1) / 3
local p1 = (c * g * t1 * t1 + 0.5 * v0 * t1 + x0 - c * (x0 + p3)) / (3 * c) - p2
-- the curve sizes
local curve0 = (p1 - x0).magnitude
local curve1 = (p2 - p3).magnitude
-- build the world CFrames for the attachments
local b = (x0 - p3).unit
local r1 = (p1 - x0).unit
local u1 = r1:Cross(b).unit
local r2 = (p2 - p3).unit
local u2 = r2:Cross(b).unit
b = u1:Cross(r1).unit
local cf1 = CFrame.new(x0.x, x0.y, x0.z, r1.x, u1.x, b.x, r1.y, u1.y, b.y, r1.z, u1.z, b.z)
local cf2 = CFrame.new(p3.x, p3.y, p3.z, r2.x, u2.x, b.x, r2.y, u2.y, b.y, r2.z, u2.z, b.z)
return curve0, -curve1, cf1, cf2
end
local function createAndSetBeam(g, v0, x0, endTime, color)
local t1 = endTime or 1 -- projectile time when in expires, or any number you want tbh
local curve0, curve1, cf1, cf2 = beamProjectile(g, v0, x0, t1)
local beam, attach0, attach1 = createBeamInProjectileMotionPath()
beam.CurveSize0 = curve0
beam.CurveSize1 = curve1
beam.FaceCamera = true
beam.Segments = 50 * math.round(t1 * 3)
if color then
beam.Color = ColorSequence.new(color)
end
-- convert world space CFrames to be relative to the attachment parent
attach0.CFrame = attach0.Parent.CFrame:Inverse() * cf1
attach1.CFrame = attach1.Parent.CFrame:Inverse() * cf2
return beam, attach0, attach1
end
Club velocities if needed
return {
{
Name = "Driver",
HeightVelocity = 370,
DistanceVelocity = 660
},
{
Name = "3 Wood",
HeightVelocity = 390,
DistanceVelocity = 635
},
{
Name = "5 Wood",
HeightVelocity = 410,
DistanceVelocity = 555
},
{
Name = "3 Iron",
HeightVelocity = 430,
DistanceVelocity = 505
},
{
Name = "4 Iron",
HeightVelocity = 450,
DistanceVelocity = 450
},
{
Name = "5 Iron",
HeightVelocity = 470,
DistanceVelocity = 415
},
{
Name = "6 Iron",
HeightVelocity = 490,
DistanceVelocity = 375
},
{
Name = "7 Iron",
HeightVelocity = 490,
DistanceVelocity = 345
},
{
Name = "8 Iron",
HeightVelocity = 510,
DistanceVelocity = 315
},
{
Name = "9 Iron",
HeightVelocity = 530,
DistanceVelocity = 285
},
{
Name = "Pitching Wedge",
HeightVelocity = 550,
DistanceVelocity = 175
},
{
Name = "Gap Wedge",
HeightVelocity = 580,
DistanceVelocity = 100
},
{
Name = "Sand Wedge",
HeightVelocity = 610,
DistanceVelocity = 115
}
}
More full path resources
Theoretically it should look like this when the path is fully traced, then I fade it out on my own with TweenService
I have a feeling this cannot be achieved with beams, so I’m not sure of any other way to create my desired effect.