How would I go about making a tracking missile / part?

Sure, here you go.

local TS = game:GetService("TweenService")

local S = game.Workspace.Start
local E = game.Workspace.End
local F = game.Workspace.Follow

F.Position = S.Position
game:GetService("RunService").Heartbeat:Connect(function()
	F.CFrame = CFrame.new(F.Position, E.Position)
end)

E:GetPropertyChangedSignal("Position"):Connect(function()
	TS:Create(F, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut), {Position = E.Position}):Play()
end)

is there a way to make the part orient itself towards the end part?

This code has a number of issues:

  • Tweens are not best to used in this scenario. I think it can be performance heavy as you are creating a new tween every time the target moves.
  • If the missile or part is close to the target, notice that it moves slowly. The missile should move with a constant speed.

@BreezeOnTheDoor if you want the part to orient itself towards the target, then you need to use CFrame or any other physics constraints.

1 Like

do you know how I could do it then?

Yeah, I know. I literally just said that when I was sending the script.

The best way is to use physics. You could skip all the CFrame nonsense unless you want to be precise. Use align position and align orientation, update them every frame.

1 Like

the thing is idk how I would actually make it track… and like I said, I got barely any experience with physics and stuff… so do you know a way I could track it with those?

I am not going to give you a direct solution to your problem, but I could give my two cents on how to approach this goal. I recommend read this tutorial about understanding CFrames at a basic level so you know what functions to use in this scenario.

@BreezeOnTheDoor read the link I’ve sent here to understand how to use physics constraints.

1 Like

If you really wanted to use CFrames, you should do this every frame:

  • Find magnitude between missile and tracker
  • Set CFrame so every frame the magnitude is slowly reduced
  • use CFrame.lookat() to orient the tracker

But what you should do is use:

alr, but im wondering how I should use those physics stuff to track? like where would I start? How would I fill out those parameters

Here a better version, It’s more efficient and the speed will be constant.

Speed = 15

local S = game.Workspace.Start
local E = game.Workspace.End
local F = game.Workspace.Follow
F.Position = S.Position

local BV = Instance.new("BodyVelocity", F)
BV.MaxForce = Vector3.new(math.huge,math.huge,math.huge)

game:GetService("RunService").Heartbeat:Connect(function()
	F.CFrame = CFrame.new(F.Position, E.Position)
	BV.Velocity = F.CFrame.LookVector * Speed
end)
1 Like

Please read the link they had just sent to you.

1 Like

On initiation process:

  1. Instance a new align position and orientation. I don’t have time to fully explain how to use them so search up a tutorial
  2. Create a heartbeat or renderstep binding function
  3. Every frame, change the target position of the align position to the position of the missile, and the cframe to a new cframe of your pos looking at the missile, i think you can skip this step if you just set this stuff to follow another attachment

You’ve said that twice now. You didnt even point him or her in the direction, you just linked an article on CFrames. Don’t clog up the thread if you aren’t going to contribute anything useful.

How am I not being helpful? I am just trying to share my two cents on how to approach such problem. Everyone here is trying to help.

You’re grubbing for an answer check. All of your replies are about reading a basic article that really won’t help the poster. It’s good they read it, but if you want to be remotely helpful point them in the direction. Maybe you may know a little more than the basic CF methods, but just saying “oh use cframes” isn’t a valuable two cents.

2 Likes

Oooh, something that’s an interesting subject!

It’s always fun to make tracking projectiles, and honestly I like how they work out! Although @KultDeeri’s suggestion may work out, it’s not good performance wise as you’re calling numerous amounts of Tweens which results in a lot of network to be taken in

The way how I usually create my projectiles, are mostly physics based as that’s probably the simplest you can get with them & they’re easy to workaround with once you get to know how they work! As @TheZanderius stated, Physics I wouldn’t say the best, but definitely are a great example to show how to create a Tracking Missile/Part! Keep in mind though that there are a few things that we’ll need to use in order to accomplish this, such as:

  • Learning how the Constraint Objects work, like LinearVelocity & AngularVelocity

  • Understanding a bit of Lua Programming to know how to constantly update where our Target is going using RunService, and CFrames

  • Using a simplified .Touched Event (For this example) to activate collisions when to make the Missile explode

But don’t worry, once we finish we should have a good result of illegal use of explosives & get sent to jail making our Rocket lock onto a specific target, then the rest should be easy from there!

Step 1: Creating our Instances

Now, our first step is creating our Instances here :thinking: What we want to have are 2 things here:

  • A Target that we want to lock onto (You can easily get one through the Rig Builder inside the Model tab)
  • The Missile that’ll end all warfare

Dave: “I’m not ready to die!”

After we have those set up, we’ll have to add the following Instances to our Missile here:

  • LinearVelocity to assign the velocity for the Part to properly move
  • AngularVelocity to prevent the Part’s Rotation from constantly orientating
  • Attachment to hook onto our LinearVelocity that I’ll explain later
  • Our Script that’ll handle all the magic :sparkles:
  • (Optional) Add a Sound that’ll play upon impact, and when ended destroys the Missile

If we’ve done all these correctly, then it should look like this!

image

Now, before we move onto Step 2 here…We have to actually assign our LinearVelocity instance to our Attachment that we just created, as it requires 1 Attachment to hook onto cause otherwise our Part will just straight up fall in the V O I D

Make sure to click your LinearVelocity object, check on its Properties, and click our Attachment object! (Do the same with your AngularVelocity as well, otherwise your Missile will move like a pendulum)

Set both of the MaxForce & MaxTorque properties of the Velocity Objects to math.huge:
image - LinearVelocity
image - AngularVelocity

image

And if we’re done it and these properties show up, we can now move onto Step 2!

Step 2: The Scripting :eyes:

Now here’s where things are gonna get very interesting, the scripting aspect is the most important part here as we want to accomplish 3 main things here:

  • Checking for hit collisions via .Touched
  • Constantly looping so that the Missile changes direction when the Target moves
  • Completely ruin Dave’s life (Aka exploding him)

Now, we’re only gonna use 1 service which is our RunService that allows us to keep track with ROBLOX’s frame-by-frame loops, instead of rather just using our standardized “while true do” wait()/task.wait() globals

local RS = game:GetService("RunService")

We’ll also want to go ahead and create a couple of custom properties for our part, so that we’re able to reference them easier later on within our script:

local MaxSpeed = 25 -- This is how fast the Velocity of the Part should go
local Exploded = false -- We will use this later within our RunService loop
local MainTarget = workspace:WaitForChild("Dummy") -- Dave is not going to see the light of day ever again

local Part = script.Parent -- Just a simple shortcut to reference our Missile here
local PartConnection -- This will be explained later on

Now onto our hit collision here; We want to make sure that we’re only checking for Models that should have Humanoid objects within them, so what the first thing we’d want to do is create a local function that we’ll connect with a .Touched Event here:

local function Touched(Hit)

end 

:information_source: - The first parameter of a .Touched Event is the Hit Part that collided with it :wink: (Examples being the Right Arm of a Character, or a Car Tire from the Model of an Old Ford)
:warning: - This can throw back errors if not handled properly, such as no frequent checks

Now, since we want to check for the Target Model (As .Touched gives only the Hit Part back), we will have to reference the Hit Part’s Parent to be able to obtain it that way:

local Target = Hit.Parent

if not Target then return end

And if say, there isn’t an exact Parent within the Part then we can go ahead and return our function which prevents it from running any more line of code :L

Next, we’ll check for the Humanoid of the Model:

local Hum = Target:FindFirstChildOfClass("Humanoid")

if Hum ~= nil then
    PartConnection:Disconnect()
		
	Exploded = true

    for _, Part in pairs(Target:GetDescendants()) do
		if Part:IsA("BasePart") then
			Part:BreakJoints()
		end
	end
		
	local Explosion = Instance.new("Explosion")
	Explosion.Position = Part.Position
	Explosion.Parent = workspace
		
    Part.Explode:Play()
	Part.Anchored = true
	Part.Transparency = 1
		
	Part.Explode.Ended:Wait()
		
	Part:Destroy()
end

Now, this may look like a lot BUT we’ll go ahead and slowly discuss what each thing does here:

  • if Hum ~= nil is just simply checking if the Humanoid we’re looking for inside our Model, is valid & able to be obtained

  • PartConnection:Disconnect() is kinda like a debounce, except when you call this it only fires once and can never be used again (You can read more about it here if you’re interested)

  • We’re setting Exploded = true to indicate that our Missile has exploded

  • for _, Part in pairs, now here we’re obtaining every singular object within our Target using the GetDescendants() method, and we can loop through every individual part to check if it’s a valid BasePart object to be able to call BreakJoints() on it (Or in simple terms, Model go bye bye)

  • We’re also creating an Explosion to add an effect to said “Missile”, to make it look more cool :sunglasses:

  • Part.Explode is referring to our Missile, so we’re obtaining our Explode Sound and Playing that

  • Part.Anchored & Part.Transparency are both properties

  • We also call Part.Explode.Ended:Wait() to yield until the Sound has ended, and then we can fully remove our Part

And lastly, we have to connect our Event

PartConnection = Part.Touched:Connect(Touched)

Overall, our Touched function should look like this now:

local Part = script.Parent

local PartConnection
local function Touched(Hit)
	local Target = Hit.Parent
	
	if not Target then return end
	
	local Hum = Target:FindFirstChildOfClass("Humanoid")
	
	if Hum ~= nil then
		PartConnection:Disconnect()
		
		Exploded = true
		
		for _, Part in pairs(Target:GetDescendants()) do
			if Part:IsA("BasePart") then
				Part:BreakJoints()
			end
		end
		
		local Explosion = Instance.new("Explosion")
		Explosion.Position = Part.Position
		Explosion.Parent = workspace
		
		Part.Explode:Play()
		Part.Anchored = true
		Part.Transparency = 1
		
		Part.Explode.Ended:Wait()
		
		Part:Destroy()
	end
end

PartConnection = Part.Touched:Connect(Touched)

It’s looking good so far! But wait, how are gonna constantly update it? Well, remember that Exploded variable we made a while back? We’re gonna use that within a while true do loop, except replace the “loop” with our own variable “Exploded” instead :smirk:

while not Exploded do
	Part.CFrame = CFrame.new(Part.Position, MainTarget.HumanoidRootPart.Position)
	Part.LinearVelocity.VectorVelocity = Part.CFrame.LookVector * MaxSpeed
	RS.Stepped:Wait()
end

Now, since at the start we defined local Exploded = false, we want to include the not operator (Which is basically the opposite, so not Exploded == true)

A couple things more here that shouldn’t be too hard to explain:

  • Part.CFrame is changing its CFrame (Orientational & Positional Values) so that it’s able to properly look at our Target, whilst keeping its position as well! The main idea here, is that in our example we’re going 2 parameters for this constructor here:

    • The first parameter is our Position we want our Missile to be, possibly in the center like Vector3.new(0, 0, 0) or even up in the sky! (Vector3.new(0, 500, 0)

    • The second parameter is the Position the Part should look at, now this one is important as the Part will face forward (You can add a Decal to your Part and see what Front Face your Missile is at), but it’ll still stay at our Position from our first parameter here

  • Part.LinearVelocity.VectorVelocity = Part.CFrame.LookVector would move our Part in the current direction it’s facing

    • :information_source: - Keep in mind! LookVector will always have a max of 1 in this scenario for each axis, so if we want to increase our speed we’ll have to multiply by our MaxSpeed variable (Which is 25)
  • Each RunService Event is different on how it runs, RS.Stepped:Wait() would fire for each frame prior to the Physics Simulation, so that’s what we’ll use for this example

Hopefully though, our full result should look like this:

local RS = game:GetService("RunService")

local MaxSpeed = 25
local Exploded = false
local MainTarget = workspace:WaitForChild("Dummy")

local Part = script.Parent

local PartConnection
local function Touched(Hit)
	local Target = Hit.Parent
	
	if not Target then return end
	
	local Hum = Target:FindFirstChildOfClass("Humanoid")
	
	if Hum ~= nil then
		PartConnection:Disconnect()
		
		Exploded = true
		
		for _, Part in pairs(Target:GetDescendants()) do
			if Part:IsA("BasePart") then
				Part:BreakJoints()
			end
		end
		
		local Explosion = Instance.new("Explosion")
		Explosion.Position = Part.Position
		Explosion.Parent = workspace
		
		Part.Explode:Play()
		Part.Anchored = true
		Part.Transparency = 1
		
		Part.Explode.Ended:Wait()
		
		Part:Destroy()
	end
end

PartConnection = Part.Touched:Connect(Touched)

while not Exploded do
	Part.CFrame = CFrame.new(Part.Position, MainTarget.HumanoidRootPart.Position)
	Part.LinearVelocity.VectorVelocity = Part.CFrame.LookVector * MaxSpeed
	RS.Stepped:Wait()
end

And now, it’s time to move onto the exciting part! The Testing :eyes:

Step 3: The Testing

Now, we have our Script alongside our Instances ready to fire up! If you’ve done everything correctly, then our Missile should move & target Dave; our test dummy!

We’ll do 2 tests: One without moving Dave, and one with moving Dave

Here’s Test #1:

As you can see here, our Missile has completely obliterated poor Dave & all his Body Parts have scattered everywhere so Test #1 was a success!

Now, let’s try Test #2 with moving Dave! (Spoiler Alert: Dave FREAKING DIES)

But as you can see from these 2 tests, both were successful! And it should hopefully give you a better insight on how to creating tracking parts!

If you do have any questions, please feel free to ask if you need to! :slightly_smiling_face:

6 Likes

oh my god it looks like you spent 10 hours on that tysm

I do have a question, what if the target is a part, rather than a humanoid. For example, a flying aircraft. The original intention was to make this for a rocket launcher made for shooting down planes / vehicles.