Trying to make a homing missile launcher

I made a homing missile launcher that follows the nearest HumanoidRootPart of any R15 or R6 player and NPC, it works great except for one problem. The missile will always chase the person who fired it because that’s the closest target for the missile. How can I tell that missile to ignore and not chase the player who fired it? This way it will look for another nearby target that isn’t the same person who fired it. I know there are ways to do this but I can’t seem to figure out how to do it myself. The launcher is a modified version of Roblox’s rocket launcher so I added a few things like replacing the code in the disabled Rocket script with the mechanism that makes the missile focus on the player. I wanna tell the missile to ignore the original creator who fired it in the Rocket script.

This is an example of the problem.

Here is a test place that you can open in Studio to fix the problem. Make the missile ignore the person who fired it - Roblox

When you fire the missile it will chase you cause you are the closest target, but if you get farther away than the test dummy then the missile will change it’s focus on the closest test dummy. I just want the missile to ignore the original creator who fired it. If you can fix it then send me a model or place with the fixed item. I’ll also allow you to keep one for yourself as a reward since there is like no homing missile launchers that actually work anymore.

3 Likes

You can use the Players:GetPlayerFromCharacter function to check if the character model belongs to a player. If it doesn’t, then continue.

2 Likes

The fix should be fairly easy. When getting the closest character check if the character is not the character of the player that fired the launcher.
Example:

if Player.Character ~= Target then
    --Code stuff
end

Putting this if statement before checking if the Target is closer than the closest one or not should fix your issue.

If this doesn’t fix your issue please reply with the code that you use to get the closest Target :slight_smile:

1 Like

Nope doesn’t work. This is the script that makes the missile look at the nearest player.

function findTorso(pos)
local torso = nil
local dist = 35
local child = workspace:children()
for i=1, #child do
if child[i].className == “Model” then
local h = child[i]:findFirstChild(“Humanoid”)
if h ~= nil then
local check = child[i]:findFirstChild(“HumanoidRootPart”)
if check ~= nil then
if (check.Position - pos).magnitude < dist then
torso = check
dist = (check.Position - pos).magnitude
end
end
end
end
end
return torso
end

while true do
wait()
local torso = findTorso(script.Parent.Position)
if torso ~= nil then
script.Parent.CFrame = CFrame.new(script.Parent.Position, torso.Position)
end
end

The place is uncopylocked if you need to have a closer look. Make the missile ignore the person who fired it - Roblox

Here’s what I think you could do

  • Create an ObjectValue for the rocket, and set the value as the Character who fired it

  • If your tool is easily activated with just an Activated Event, you could just simply set the value to the HumanoidRootPart

  • Check if your Rocket’s ObjectValue is the same as target’s HRP, if it is then ignore that

local Tool = script.Parent

Tool.Activated:Connect(function()
    local Character = Tool.Parent
    local HRP = Character.HumanoidRootPart
    local Rocket = --Do your rocket cloning here
    if HRP then
        Rocket.IgnoreCaster.Value = HRP --Set the ObjectValue to ignore the character
    end
end)

And then on your chase script, you can do this:

local IgnoreCast = script.Parent.IgnoreCaster

function findTorso(pos)
    local torso = nil
    local dist = 35
    local child = workspace:GetChildren()
    for i=1, #child do
        if child[i].className == "Model" then
        local h = child[i]:findFirstChild("Humanoid")
            if h ~= nil then
                local check = child[i]:FindFirstChild("HumanoidRootPart")
                if check ~= nil then
                    if (check.Position - pos).magnitude < dist and IgnoreCast.Value ~= check then --Implementing another check to ignore the caster
                        torso = check
                        dist = (check.Position - pos).magnitude
                    end
                end
            end
        end
    end
    return torso
end

while true do
    wait()
    local torso = findTorso(script.Parent.Position)
    if torso ~= nil then
        script.Parent.CFrame = CFrame.new(script.Parent.Position, torso.Position)
    end
end

It doesn’t work, idk if I did this right. I put the ObjectValue inside the chase script and also in the server script, neither of them worked.


–| Constants |–

local GRAVITY_ACCELERATION = workspace.Gravity

local RELOAD_TIME = 4 – Seconds until tool can be used again
local ROCKET_SPEED = 0 – Speed of the projectile

local MISSILE_MESH_ID = ‘http://www.roblox.com/asset/?id=2251534
local MISSILE_MESH_SCALE = Vector3.new(0.35, 0.35, 0.25)
local ROCKET_PART_SIZE = Vector3.new(1.2, 1.2, 3.27)


–| Variables |–

local DebrisService = game:GetService(‘Debris’)
local PlayersService = game:GetService(‘Players’)

local MyPlayer

local Tool = script.Parent
local ToolHandle = Tool:WaitForChild(“Handle”)

local MouseLoc = Tool:WaitForChild(“MouseLoc”,10)

local RocketScript = script:WaitForChild(‘Rocket’)
local RocketBoost = script:WaitForChild(‘BodyVelocity’)
local SwooshSound = script:WaitForChild(‘Swoosh’)
local BoomSound = script:WaitForChild(‘Boom’)

–NOTE: We create the rocket once and then clone it when the player fires
local Rocket = Instance.new(‘Part’) do
– Set up the rocket part
Rocket.Name = ‘Rocket’
Rocket.FormFactor = Enum.FormFactor.Custom --NOTE: This must be done before changing Size
Rocket.Size = ROCKET_PART_SIZE
Rocket.CanCollide = false

-- Add the mesh
local mesh = Instance.new('SpecialMesh', Rocket)
mesh.MeshId = MISSILE_MESH_ID
mesh.Scale = MISSILE_MESH_SCALE

-- Add fire
local fire = Instance.new('Fire', Rocket)
fire.Heat = 5
fire.Size = 2

-- Clone the sounds and set Boom to PlayOnRemove
local swooshSoundClone = SwooshSound:Clone()
swooshSoundClone.Parent = Rocket
local boomSoundClone = BoomSound:Clone()
boomSoundClone.PlayOnRemove = true
boomSoundClone.Parent = Rocket

-- Attach creator tags to the rocket early on
local creatorTag = Instance.new('ObjectValue', Rocket)
creatorTag.Value = MyPlayer
creatorTag.Name = 'creator' --NOTE: Must be called 'creator' for website stats
local iconTag = Instance.new('StringValue', creatorTag)
iconTag.Value = Tool.TextureId
iconTag.Name = 'icon'

-- Finally, clone the rocket script and enable it
local rocketScriptClone = RocketScript:Clone()
rocketScriptClone.Parent = Rocket
rocketScriptClone.Disabled = false
local rocketBoostClone = RocketBoost:Clone()
rocketBoostClone.Parent = Rocket

end


–| Functions |–

local function OnActivated()
local Character = Tool.Parent
local HRP = Character.HumanoidRootPart
local rocketClone = Rocket:Clone()
local Rocket = rocketClone
if HRP then
Rocket.IgnoreCaster.Value = HRP --Set the ObjectValue to ignore the character
local myModel = MyPlayer.Character
if Tool.Enabled and myModel and myModel:FindFirstChildOfClass(“Humanoid”) and myModel.Humanoid.Health > 0 then
Tool.Enabled = false
local Pos = MouseLoc:InvokeClient(MyPlayer)
– Create a clone of Rocket and set its color

	DebrisService:AddItem(rocketClone, 30)
	rocketClone.BrickColor = MyPlayer.TeamColor

	-- Position the rocket clone and launch!
	local spawnPosition = (ToolHandle.CFrame * CFrame.new(5, 0, 0)).p
	rocketClone.CFrame = CFrame.new(spawnPosition, Pos) --NOTE: This must be done before assigning Parent
	rocketClone.Velocity = rocketClone.CFrame.lookVector * ROCKET_SPEED --NOTE: This should be done before assigning Parent
	rocketClone.Parent = workspace
	rocketClone:SetNetworkOwner(nil)

	wait(RELOAD_TIME)

	Tool.Enabled = true
end
end
end

function OnEquipped()
MyPlayer = PlayersService:GetPlayerFromCharacter(Tool.Parent)
end


–| Script Logic |–

Tool.Equipped:Connect(OnEquipped)
Tool.Activated:Connect(OnActivated)

You should just have the ObjectValue inside the Rocket Part alone, no need to put it inside the ChaseScript as well

So it’s a part that gets created, alright in your Instance.new() setup do this as well:

local IgnoreCaster = Instance.new("ObjectValue")
IgnoreCaster.Name = "IgnoreCaster"
IgnoreCaster.Parent = Rocket

Then change your Rocket.IgnoreCaster.Value to the IgnoreCaster.Value, try that and see if that changes anything?

2 Likes

This is exactly what I wanted, thank you for helping me figure this out! Next I’ll try and simplify the whole thing and remove the no longer useful parts of the script.