Homing Missile Support | How do I make a damageable homing missile?

Your code seems good so far. Could I know what script uses the FireRocket(target, rocket_health). Are you sure that if you call FireRocket once, it launches only one rocket? You should try inserting “print” statements, to see if FireRocket is not being called more than it should be

It’s used in the same script: heres the entirety of it:

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local TweenService = game:GetService("TweenService")
local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Debris = game:GetService("Debris")

local tweenInfo = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local FX_Remotes = ReplicatedStorage:WaitForChild("FX_Remotes")
local BossAssets = ServerStorage:WaitForChild("BossAssets")

local Infernal = script.Parent
local HRP = Infernal:WaitForChild("HumanoidRootPart")
local BodyPosition = HRP:WaitForChild("BodyPosition")
local Humanoid = Infernal:WaitForChild("Humanoid")

local Effects = workspace:WaitForChild("Effects")
local SoundLibrary = workspace:WaitForChild("Sounds"):WaitForChild("Infernal")

BodyPosition.Position = HRP.Position + Vector3.new(0, script.Height.Value, 0) + Vector3.new(0, math.random(-1.5,1.5), 0)

local Waypoints = workspace:WaitForChild("BossWaypoints")

local Track_IDLE = script:WaitForChild("Idle")
local Track_CHARGE = script:WaitForChild("Charge")
local Track_CHARGE_FINISH = script:WaitForChild("ChargeFinish")

local IdleAnimation = Humanoid:LoadAnimation(Track_IDLE)
local ChargeAnimation = Humanoid:LoadAnimation(Track_CHARGE)
local ChargeFinishAnimation = Humanoid:LoadAnimation(Track_CHARGE_FINISH)

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {Infernal}

local ChargeDamage = 30
local MissileDamage = 15

local InvulnerabilityFrame = false

local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local explosiveSounds = {
	"rbxassetid://13395198479", --1
	"rbxassetid://13395198204", --2
	"rbxassetid://13395198752", --3
	"rbxassetid://13395199326", --4
}

local lastPos
local RANGE = math.huge

IdleAnimation:Play()

local function FaceTarget(target)
	Infernal:SetPrimaryPartCFrame(CFrame.lookAt(HRP.Position, target.HumanoidRootPart.Position * Vector3.new(1, 0, 1) + target.HumanoidRootPart.Position * Vector3.new(0, 1, 0)))
end

local function findTarget()
	local players = Players:GetPlayers()
	local maxDistance = RANGE
	local nearestTarget

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (HRP.Position - target.HumanoidRootPart.Position).Magnitude

			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end

	print("BOSS SYSTEM | Target Found!")
	return nearestTarget
end

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)
	path:ComputeAsync(HRP.Position, destination.Position)
	return path	
end

local function ExplodeRocket(Rocket, RocketPrimary)
	local Explosion = Instance.new("Explosion", RocketPrimary)
	Explosion.BlastRadius = 0
	Rocket.Humanoid.Health = 0
	task.wait(1)
	Rocket:Destroy()
	local Sound = Instance.new("Sound", Effects)
	Sound.SoundId = explosiveSounds[math.random(1, #explosiveSounds)]
	Sound:Play()
	Debris:AddItem(Sound, Sound.TimeLength)
end

local function FireRocket(target, rocket_health)
	local Missile = BossAssets:WaitForChild("InfernalMissile"):Clone()	
	local MissilePrimary = Missile.HumanoidRootPart
	
	local MissileTarget = Instance.new("Part", workspace.bin)
	MissileTarget.Name = "MissileTarget"
	MissileTarget.Size = Vector3.new(1,1,1)
	MissileTarget.CanCollide = false
	MissileTarget.Transparency = 1
	MissileTarget.Anchored = true
	
	local AttachmentTarget = Instance.new("Attachment", MissileTarget)
	AttachmentTarget.Name = "TargetAttach"
	AttachmentTarget.Orientation = Vector3.new(-90, -180, 0)
	
	MissilePrimary.AlignPosition.Attachment1 = AttachmentTarget
	MissilePrimary.AlignPosition.Attachment1 = AttachmentTarget
	
	
	task.spawn(function()
		while true do
			task.wait(0.15)
			if Missile.Humanoid.Health ~= 0 then
				
			end
		end
	end)
	
	Missile.Parent = Effects	
	Missile.HumanoidRootPart:SetNetworkOwner(nil)
	Missile:MoveTo(Infernal.PrimaryPart.Position + Vector3.new(0, 10, 0))
	Debris:AddItem(Missile, 250)
	
	Missile.Humanoid.MaxHealth = rocket_health
	Missile.Humanoid.Health = rocket_health
	
	Missile.Humanoid.Died:Connect(function()
		MissileTarget:Destroy()
		ExplodeRocket(Missile, MissilePrimary)
	end)
	
	MissilePrimary.Touched:Connect(function(Hit)
		if not InvulnerabilityFrame then
			if Hit ~= nil then
				if Players:GetPlayerFromCharacter(Hit.Parent) then
					InvulnerabilityFrame = true
					
					ExplodeRocket(Missile, MissilePrimary)

					local Player = Players:GetPlayerFromCharacter(Hit.Parent)

					local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
					TargetHumanoid:TakeDamage(MissileDamage)
					FX_Remotes.Camera.SmallBump:FireAllClients()
					task.wait(1)
					InvulnerabilityFrame = false
				end
			end
		end
	end)
end

local function Charge(target)
	local distance = (HRP.Position - target.HumanoidRootPart.Position).Magnitude
	local debounce = false

	if distance < 850 then
		
		FaceTarget(target)
		
		local Number = math.random(1,10)
		
		if Number == 1 then
			FireRocket(target, 50)
			SoundLibrary.Missile:Play()
		end
		
		BodyPosition.Position = target.HumanoidRootPart.Position + Vector3.new(0, 5, 0)
		SoundLibrary.Dash:Play()
		IdleAnimation:Stop()
		ChargeAnimation:Play()

		HRP.HITBOX.Touched:Connect(function(Hit)
			if not InvulnerabilityFrame then
				if Hit ~= nil then
					if Players:GetPlayerFromCharacter(Hit.Parent) then
						InvulnerabilityFrame = true
						
						local Player = Players:GetPlayerFromCharacter(Hit.Parent)

						local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
						TargetHumanoid:TakeDamage(ChargeDamage)
						FX_Remotes.Camera.Explosion:FireAllClients()
						task.wait(2)
						InvulnerabilityFrame = false
					end
				end
			end
		end)

		task.wait(SoundLibrary.Dash.TimeLength + 0.1)
		ChargeAnimation:Stop()
		ChargeFinishAnimation:Play()
		task.wait(0.15)
		IdleAnimation:Play()
	end
end

local function walkTo(destination)
	print("BOSS SYSTEM | Patrolling..")

	if destination then

		local target = findTarget()

		if target and target.Humanoid.Health > 0 then

			print("BOSS SYSTEM | Target Found:" .. target.Name)

			lastPos = target.HumanoidRootPart.Position
			Charge(target)
			return
		else
			if lastPos then
				BodyPosition.Position = lastPos
				task.wait(1)
				lastPos = nil
				return
			end
		end
	end
end

local function patrol()
	local waypoints = Waypoints:GetChildren()
	local randomNum = math.random(1, #waypoints)
	walkTo(waypoints[randomNum])
end

task.spawn(function()
	while task.wait(0.2) do
		patrol()
	end
end)

Humanoid.Died:Connect(function()
	local target = findTarget()

	if target and target.Humanoid.Health > 0 then

		local Player = Players:GetPlayerFromCharacter(target)

		FX_Remotes:WaitForChild("BossHealthBar"):FireClient(Player,"STOP", Infernal)

		local Audio = workspace:WaitForChild("Audio")
		local Music = Audio:WaitForChild("Music")
		local Tween = TweenService:Create(Music.InfernalTheme, tweenInfo, {Volume = 0})
		Tween:Play()
		Tween.Completed:Wait()
		Music.InfernalTheme:Stop()

		task.wait(0.15)
		Infernal:Destroy()
	end
end)

After tracing the FireRocket, it lead me to this:

task.spawn(function()
	while task.wait(0.2) do
		patrol()
	end
end)

This is worrisome, try changing the task.wait to a bigger number, because
the patrol() fires walkTo(waypoints[randomNum])
walkTo(waypoints[randomNum]) fires Charge(target)
Charge(target) fires FireRocket(target, 50)

Alright, I’ll make sure to do that then.

Would 1 second work?

EDIT: After testing this, the boss attacks got delayed, which is a good thing since it makes it fair instead. But the missile still flops onto the ground doing nothing.

ok. Are you sure the AlignPosition is enabled?

MissilePrimary.AlignPosition.Enabled = true

or try

MissileTarget.Transparency = 0.5

to see what’s happening

don’t you think stops the code?

repeat task.wait(0.1)
		MissileTarget.Position = target.HumanoidRootPart.Position
until Missile.Humanoid.Died

try

coroutine.wrap(function()
	repeat task.wait(0.1)
		MissileTarget.Position = target.HumanoidRootPart.Position
	until Missile.Humanoid.Died
end)()

I’ve tried this, but the missile seems to just:

do nothing but sit there. Heres the new code:

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local TweenService = game:GetService("TweenService")
local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Debris = game:GetService("Debris")

local tweenInfo = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local FX_Remotes = ReplicatedStorage:WaitForChild("FX_Remotes")
local BossAssets = ServerStorage:WaitForChild("BossAssets")

local Infernal = script.Parent
local HRP = Infernal:WaitForChild("HumanoidRootPart")
local BodyPosition = HRP:WaitForChild("BodyPosition")
local Humanoid = Infernal:WaitForChild("Humanoid")

local Effects = workspace:WaitForChild("Effects")
local SoundLibrary = workspace:WaitForChild("Sounds"):WaitForChild("Infernal")

BodyPosition.Position = HRP.Position + Vector3.new(0, script.Height.Value, 0) + Vector3.new(0, math.random(-1.5,1.5), 0)

local Waypoints = workspace:WaitForChild("BossWaypoints")

local Track_IDLE = script:WaitForChild("Idle")
local Track_CHARGE = script:WaitForChild("Charge")
local Track_CHARGE_FINISH = script:WaitForChild("ChargeFinish")

local IdleAnimation = Humanoid:LoadAnimation(Track_IDLE)
local ChargeAnimation = Humanoid:LoadAnimation(Track_CHARGE)
local ChargeFinishAnimation = Humanoid:LoadAnimation(Track_CHARGE_FINISH)

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {Infernal}

local ChargeDamage = 30
local MissileDamage = 15

local InvulnerabilityFrame = false

local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local explosiveSounds = {
	"rbxassetid://13395198479", --1
	"rbxassetid://13395198204", --2
	"rbxassetid://13395198752", --3
	"rbxassetid://13395199326", --4
}

local lastPos
local RANGE = math.huge

IdleAnimation:Play()

local function FaceTarget(target)
	Infernal:SetPrimaryPartCFrame(CFrame.lookAt(HRP.Position, target.HumanoidRootPart.Position * Vector3.new(1, 0, 1) + target.HumanoidRootPart.Position * Vector3.new(0, 1, 0)))
end

local function findTarget()
	local players = Players:GetPlayers()
	local maxDistance = RANGE
	local nearestTarget

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (HRP.Position - target.HumanoidRootPart.Position).Magnitude

			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end

	print("BOSS SYSTEM | Target Found!")
	return nearestTarget
end

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)
	path:ComputeAsync(HRP.Position, destination.Position)
	return path	
end

local function ExplodeRocket(Rocket, RocketPrimary)
	local Explosion = Instance.new("Explosion", RocketPrimary)
	Explosion.BlastRadius = 0
	Rocket.Humanoid.Health = 0
	task.wait(1)
	Rocket:Destroy()
	local Sound = Instance.new("Sound", Effects)
	Sound.SoundId = explosiveSounds[math.random(1, #explosiveSounds)]
	Sound:Play()
	Debris:AddItem(Sound, Sound.TimeLength)
end

local function FireRocket(target, rocket_health)
	local Missile = BossAssets:WaitForChild("InfernalMissile"):Clone()	
	local MissilePrimary = Missile.HumanoidRootPart
	
	local MissileTarget = Instance.new("Part", workspace.bin)
	MissileTarget.Name = "MissileTarget"
	MissileTarget.Size = Vector3.new(1,1,1)
	MissileTarget.CanCollide = false
	MissileTarget.Transparency = 1
	MissileTarget.Anchored = true
	
	local AttachmentTarget = Instance.new("Attachment", MissileTarget)
	AttachmentTarget.Name = "TargetAttach"
	AttachmentTarget.Orientation = Vector3.new(-90, -180, 0)
	
	MissilePrimary.AlignOrientation.Attachment1 = AttachmentTarget
	MissilePrimary.AlignPosition.Attachment1 = AttachmentTarget
	
	coroutine.wrap(function()
		repeat task.wait(0.1)
			MissileTarget.Position = target.HumanoidRootPart.Position
		until Missile.Humanoid.Died
	end)()
	
	Missile.Parent = Effects	
	Missile.HumanoidRootPart:SetNetworkOwner(nil)
	Missile:MoveTo(Infernal.PrimaryPart.Position + Vector3.new(0, 10, 0))
	Debris:AddItem(Missile, 250)
	
	Missile.Humanoid.MaxHealth = rocket_health
	Missile.Humanoid.Health = rocket_health
	
	Missile.Humanoid.Died:Connect(function()
		MissileTarget:Destroy()
		ExplodeRocket(Missile, MissilePrimary)
	end)
	
	MissilePrimary.Touched:Connect(function(Hit)
		if not InvulnerabilityFrame then
			if Hit ~= nil then
				if Players:GetPlayerFromCharacter(Hit.Parent) then
					InvulnerabilityFrame = true
					
					ExplodeRocket(Missile, MissilePrimary)

					local Player = Players:GetPlayerFromCharacter(Hit.Parent)

					local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
					TargetHumanoid:TakeDamage(MissileDamage)
					FX_Remotes.Camera.SmallBump:FireAllClients()
					task.wait(1)
					InvulnerabilityFrame = false
				end
			end
		end
	end)
end

local function Charge(target)
	local distance = (HRP.Position - target.HumanoidRootPart.Position).Magnitude
	local debounce = false

	if distance < 850 then
		
		FaceTarget(target)
		
		local Number = math.random(1,10)
		
		if Number == 1 then
			FireRocket(target, 50)
			SoundLibrary.Missile:Play()
		end
		
		BodyPosition.Position = target.HumanoidRootPart.Position + Vector3.new(0, 5, 0)
		SoundLibrary.Dash:Play()
		IdleAnimation:Stop()
		ChargeAnimation:Play()

		HRP.HITBOX.Touched:Connect(function(Hit)
			if not InvulnerabilityFrame then
				if Hit ~= nil then
					if Players:GetPlayerFromCharacter(Hit.Parent) then
						InvulnerabilityFrame = true
						
						local Player = Players:GetPlayerFromCharacter(Hit.Parent)

						local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
						TargetHumanoid:TakeDamage(ChargeDamage)
						FX_Remotes.Camera.Explosion:FireAllClients()
						task.wait(2)
						InvulnerabilityFrame = false
					end
				end
			end
		end)

		task.wait(SoundLibrary.Dash.TimeLength + 0.1)
		ChargeAnimation:Stop()
		ChargeFinishAnimation:Play()
		task.wait(0.15)
		IdleAnimation:Play()
	end
end

local function walkTo(destination)
	print("BOSS SYSTEM | Patrolling..")

	if destination then

		local target = findTarget()

		if target and target.Humanoid.Health > 0 then

			print("BOSS SYSTEM | Target Found:" .. target.Name)

			lastPos = target.HumanoidRootPart.Position
			Charge(target)
			return
		else
			if lastPos then
				BodyPosition.Position = lastPos
				task.wait(1)
				lastPos = nil
				return
			end
		end
	end
end

local function patrol()
	local waypoints = Waypoints:GetChildren()
	local randomNum = math.random(1, #waypoints)
	walkTo(waypoints[randomNum])
end

task.spawn(function()
	while task.wait(0.35) do
		patrol()
	end
end)

Humanoid.Died:Connect(function()
	local target = findTarget()

	if target and target.Humanoid.Health > 0 then

		local Player = Players:GetPlayerFromCharacter(target)

		FX_Remotes:WaitForChild("BossHealthBar"):FireClient(Player,"STOP", Infernal)

		local Audio = workspace:WaitForChild("Audio")
		local Music = Audio:WaitForChild("Music")
		local Tween = TweenService:Create(Music.InfernalTheme, tweenInfo, {Volume = 0})
		Tween:Play()
		Tween.Completed:Wait()
		Music.InfernalTheme:Stop()

		task.wait(0.15)
		Infernal:Destroy()
	end
end)

I think the missile stuff may need a rework.

yes, it needs a rework, and a better structure. lets start over
Did the rocket worked in the past (like it goes to the target by flying)?

Sort of, I can find a old version of the script working if you want to.

Ok (I hope its the alignposition version.) I gotta go srr. But you should try replicating the same properties in a script and then have a another separate function that gives those properties to the missile. I believe this is will do

Here is the old version, it includes the problem of it simply just breaking the players physics since the attachment is in the players HRP. So maybe that part method could work here where its not in the player but a seperate part?

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local TweenService = game:GetService("TweenService")
local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Debris = game:GetService("Debris")

local tweenInfo = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local FX_Remotes = ReplicatedStorage:WaitForChild("FX_Remotes")
local BossAssets = ServerStorage:WaitForChild("BossAssets")

local Infernal = script.Parent
local HRP = Infernal:WaitForChild("HumanoidRootPart")
local BodyPosition = HRP:WaitForChild("BodyPosition")
local Humanoid = Infernal:WaitForChild("Humanoid")

local Effects = workspace:WaitForChild("Effects")
local SoundLibrary = workspace:WaitForChild("Sounds"):WaitForChild("Infernal")

BodyPosition.Position = HRP.Position + Vector3.new(0, script.Height.Value, 0) + Vector3.new(0, math.random(-1.5,1.5), 0)

local Waypoints = workspace:WaitForChild("BossWaypoints")

local Track_IDLE = script:WaitForChild("Idle")
local Track_CHARGE = script:WaitForChild("Charge")
local Track_CHARGE_FINISH = script:WaitForChild("ChargeFinish")

local IdleAnimation = Humanoid:LoadAnimation(Track_IDLE)
local ChargeAnimation = Humanoid:LoadAnimation(Track_CHARGE)
local ChargeFinishAnimation = Humanoid:LoadAnimation(Track_CHARGE_FINISH)

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {Infernal}

local ChargeDamage = 30
local MissileDamage = 15

local InvulnerabilityFrame = false

local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = true,
}

local explosiveSounds = {
	"rbxassetid://13395198479", --1
	"rbxassetid://13395198204", --2
	"rbxassetid://13395198752", --3
	"rbxassetid://13395199326", --4
}

local lastPos
local RANGE = math.huge

IdleAnimation:Play()

local function FaceTarget(target)
	Infernal:SetPrimaryPartCFrame(CFrame.lookAt(HRP.Position, target.HumanoidRootPart.Position * Vector3.new(1, 0, 1) + target.HumanoidRootPart.Position * Vector3.new(0, 1, 0)))
end

local function findTarget()
	local players = Players:GetPlayers()
	local maxDistance = RANGE
	local nearestTarget

	for i, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (HRP.Position - target.HumanoidRootPart.Position).Magnitude

			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end

	print("BOSS SYSTEM | Target Found!")
	return nearestTarget
end

local function getPath(destination)
	local path = PathfindingService:CreatePath(pathParams)
	path:ComputeAsync(HRP.Position, destination.Position)
	return path	
end

local function ExplodeRocket(Rocket, RocketPrimary)
	local Explosion = Instance.new("Explosion", RocketPrimary)
	Explosion.BlastRadius = 0
	Rocket.Humanoid.Health = 0
	task.wait(1)
	Rocket:Destroy()
	local Sound = Instance.new("Sound", Effects)
	Sound.SoundId = explosiveSounds[math.random(1, #explosiveSounds)]
	Sound:Play()
	Debris:AddItem(Sound, Sound.TimeLength)
end

local function FireRocket(target, rocket_health)
	local Missile = BossAssets:WaitForChild("InfernalMissile"):Clone()
	Missile.Parent = Effects
	Missile:MoveTo(Infernal.PrimaryPart.Position + Vector3.new(0, 10, 0))
	Debris:AddItem(Missile, 250)

	Missile.Humanoid.MaxHealth = rocket_health
	Missile.Humanoid.Health = rocket_health

	local MissilePrimary = Missile.HumanoidRootPart
	MissilePrimary.AlignPosition.Attachment1 = target.HumanoidRootPart.TargetAttachment
	MissilePrimary.AlignPosition.Attachment1 = target.HumanoidRootPart.TargetAttachment

	Missile.Humanoid.Died:Connect(function(hit)
		local Explosion = Instance.new("Explosion", MissilePrimary)
		Explosion.BlastRadius = 0
		Explosion.BlastPressure = 0
		task.wait(1)
		Missile:Destroy()
		local Sound = Instance.new("Sound", Effects)
		Sound.SoundId = explosiveSounds[math.random(1, #explosiveSounds)]
		Sound:Play()
		Debris:AddItem(Sound, Sound.TimeLength)
	end)

	MissilePrimary.Touched:Connect(function(Hit)
		if not InvulnerabilityFrame then
			if Hit ~= nil then
				if Players:GetPlayerFromCharacter(Hit.Parent) then
					InvulnerabilityFrame = true

					local Player = Players:GetPlayerFromCharacter(Hit.Parent)

					local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
					TargetHumanoid:TakeDamage(MissileDamage)
					FX_Remotes.Camera.SmallBump:FireAllClients()
					task.wait(1)
					InvulnerabilityFrame = false
				end
			end
		end
	end)
end

local function Charge(target)
	local distance = (HRP.Position - target.HumanoidRootPart.Position).Magnitude
	local debounce = false

	if distance < 850 then
		
		FaceTarget(target)
		
		local Number = math.random(1,10)
		
		if Number == 1 then
			FireRocket(target, 50)
			SoundLibrary.Missile:Play()
		end
		
		BodyPosition.Position = target.HumanoidRootPart.Position + Vector3.new(0, 5, 0)
		SoundLibrary.Dash:Play()
		IdleAnimation:Stop()
		ChargeAnimation:Play()

		HRP.HITBOX.Touched:Connect(function(Hit)
			if not InvulnerabilityFrame then
				if Hit ~= nil then
					if Players:GetPlayerFromCharacter(Hit.Parent) then
						InvulnerabilityFrame = true
						
						local Player = Players:GetPlayerFromCharacter(Hit.Parent)

						local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
						TargetHumanoid:TakeDamage(ChargeDamage)
						FX_Remotes.Camera.Explosion:FireAllClients()
						task.wait(2)
						InvulnerabilityFrame = false
					end
				end
			end
		end)

		task.wait(SoundLibrary.Dash.TimeLength + 0.1)
		ChargeAnimation:Stop()
		ChargeFinishAnimation:Play()
		task.wait(0.15)
		IdleAnimation:Play()
	end
end

local function walkTo(destination)
	print("BOSS SYSTEM | Patrolling..")

	if destination then

		local target = findTarget()

		if target and target.Humanoid.Health > 0 then

			print("BOSS SYSTEM | Target Found:" .. target.Name)

			lastPos = target.HumanoidRootPart.Position
			Charge(target)
			return
		else
			if lastPos then
				BodyPosition.Position = lastPos
				task.wait(1)
				lastPos = nil
				return
			end
		end
	end
end

local function patrol()
	local waypoints = Waypoints:GetChildren()
	local randomNum = math.random(1, #waypoints)
	walkTo(waypoints[randomNum])
end

task.spawn(function()
	while task.wait(0.35) do
		patrol()
	end
end)

Humanoid.Died:Connect(function()
	local target = findTarget()

	if target and target.Humanoid.Health > 0 then

		local Player = Players:GetPlayerFromCharacter(target)

		FX_Remotes:WaitForChild("BossHealthBar"):FireClient(Player,"STOP", Infernal)

		local Audio = workspace:WaitForChild("Audio")
		local Music = Audio:WaitForChild("Music")
		local Tween = TweenService:Create(Music.InfernalTheme, tweenInfo, {Volume = 0})
		Tween:Play()
		Tween.Completed:Wait()
		Music.InfernalTheme:Stop()

		task.wait(0.15)
		Infernal:Destroy()
	end
end)

To create a homing missile using LineForce , you can make use of the BodyForce and BodyVelocity instances to make it follow the NPC. Here’s an example code snippet that you can use as a starting point:

-- Get the NPC's position
local targetPosition = Vector3.new(0, 10, 0) -- Replace with your NPC's position

-- Create the missile
local missile = Instance.new("Part")
missile.Size = Vector3.new(2, 2, 5)
missile.Position = Vector3.new(0, 5, 0) -- Replace with your starting position
missile.BrickColor = BrickColor.new("Bright red")
missile.Parent = workspace

-- Create a BodyForce to move the missile towards the target
local bodyForce = Instance.new("BodyForce")
bodyForce.Force = Vector3.new(0, 10000, 0) -- Set the force to be in the upwards direction
bodyForce.Parent = missile

-- Create a BodyVelocity to make the missile move forward
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.Velocity = Vector3.new(0, 0, 100) -- Set the initial velocity to be in the forward direction
bodyVelocity.MaxForce = Vector3.new(100000, 100000, 100000) -- Set the max force to be high so that the missile can accelerate quickly
bodyVelocity.Parent = missile

-- Create a loop to update the missile's velocity and force
while missile.Parent do
    -- Get the direction towards the target
    local direction = (targetPosition - missile.Position).unit

    -- Set the force to move towards the target
    bodyForce.Force = direction * 10000 -- You can adjust this force value to control the missile's speed

    -- Set the velocity to move towards the target
    bodyVelocity.Velocity = direction * 100 -- You can adjust this velocity value to control the missile's speed

    -- Wait for a short amount of time before updating again
    wait(0.1)
end

-- Destroy the missile when it hits the target
missile:Destroy()

In this code, the missile is created as a Part with a red color. It is given a BodyForce instance to move it towards the target and a BodyVelocity instance to make it move forward. The while loop continuously updates the missile’s velocity and force to move it towards the target. Once the missile hits the target, it is destroyed.

You can modify this code to suit your specific needs, such as adding collision detection to detect when the missile hits the NPC and adding damage to the NPC when it is hit.

1 Like

It works perfectly! I was wondering how to make it face the player however, any ideas?

To make the missile face the player, you can use the LookAt method of the CFrame class to set the orientation of the missile’s CFrame to look towards the player. Here’s an updated code snippet that includes this functionality:

-- Get the NPC's position and the player's position
local targetPosition = Vector3.new(0, 10, 0) -- Replace with your NPC's position
local playerPosition = game.Players.LocalPlayer.Character.HumanoidRootPart.Position -- Replace with the player's position

-- Create the missile
local missile = Instance.new("Part")
missile.Size = Vector3.new(2, 2, 5)
missile.Position = Vector3.new(0, 5, 0) -- Replace with your starting position
missile.BrickColor = BrickColor.new("Bright red")
missile.Parent = workspace

-- Create a BodyForce to move the missile towards the target
local bodyForce = Instance.new("BodyForce")
bodyForce.Force = Vector3.new(0, 10000, 0) -- Set the force to be in the upwards direction
bodyForce.Parent = missile

-- Create a BodyVelocity to make the missile move forward
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.Velocity = Vector3.new(0, 0, 100) -- Set the initial velocity to be in the forward direction
bodyVelocity.MaxForce = Vector3.new(100000, 100000, 100000) -- Set the max force to be high so that the missile can accelerate quickly
bodyVelocity.Parent = missile

-- Create a loop to update the missile's velocity and force
while missile.Parent do
    -- Get the direction towards the target
    local direction = (targetPosition - missile.Position).unit

    -- Set the force to move towards the target
    bodyForce.Force = direction * 10000 -- You can adjust this force value to control the missile's speed

    -- Set the velocity to move towards the target
    bodyVelocity.Velocity = direction * 100 -- You can adjust this velocity value to control the missile's speed

    -- Set the missile's orientation to face the player
    local lookVector = (playerPosition - missile.Position).unit
    missile.CFrame = CFrame.new(missile.Position, missile.Position + lookVector)

    -- Wait for a short amount of time before updating again
    wait(0.1)
end

-- Destroy the missile when it hits the target
missile:Destroy()

In this code, the lookVector variable is computed as the unit vector in the direction towards the player. This vector is used to create a CFrame that rotates the missile to face the player. The CFrame.new method is called with the missile’s position as the origin and missile.Position + lookVector as the destination to create the desired orientation.

Note that in this code, game.Players.LocalPlayer.Character.HumanoidRootPart.Position is used to get the position of the player. If you are running this code in a server script or if you want to target a specific player instead of the local player, you will need to modify this line to get the position of the desired player.

It’s a bit hard to angle the tip of the missile towards the player, any ideas on how to make the tip of the missile more precise?

If you want to make the missile point more precisely towards the player, you can use the lookVector calculated in the previous answer to rotate the missile’s tip towards the player.

To do this, you can create a small attachment at the tip of the missile, and then use CFrame.Angles() to create a new CFrame with the desired rotation. Here’s an code snippet that shows how to do this:

-- Get the NPC's position and the player's position
local targetPosition = Vector3.new(0, 10, 0) -- Replace with your NPC's position
local playerPosition = game.Players.LocalPlayer.Character.HumanoidRootPart.Position -- Replace with the player's position

-- Create the missile
local missile = Instance.new("Part")
missile.Size = Vector3.new(2, 2, 5)
missile.Position = Vector3.new(0, 5, 0) -- Replace with your starting position
missile.BrickColor = BrickColor.new("Bright red")
missile.Parent = workspace

-- Create an attachment at the tip of the missile
local tipAttachment = Instance.new("Attachment")
tipAttachment.Parent = missile
tipAttachment.Position = Vector3.new(0, 0, missile.Size.Z/2)

-- Create a BodyForce to move the missile towards the target
local bodyForce = Instance.new("BodyForce")
bodyForce.Force = Vector3.new(0, 10000, 0) -- Set the force to be in the upwards direction
bodyForce.Parent = missile

-- Create a BodyVelocity to make the missile move forward
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.Velocity = Vector3.new(0, 0, 100) -- Set the initial velocity to be in the forward direction
bodyVelocity.MaxForce = Vector3.new(100000, 100000, 100000) -- Set the max force to be high so that the missile can accelerate quickly
bodyVelocity.Parent = missile

-- Create a loop to update the missile's velocity and force
while missile.Parent do
    -- Get the direction towards the target
    local direction = (targetPosition - missile.Position).unit

    -- Set the force to move towards the target
    bodyForce.Force = direction * 10000 -- You can adjust this force value to control the missile's speed

    -- Set the velocity to move towards the target
    bodyVelocity.Velocity = direction * 100 -- You can adjust this velocity value to control the missile's speed

    -- Set the missile's orientation to face the player
    local lookVector = (playerPosition - missile.Position).unit
    local missileCFrame = CFrame.new(missile.Position, missile.Position + lookVector)
    tipAttachment.CFrame = missileCFrame * CFrame.Angles(math.pi/2, 0, 0) -- Rotate the attachment to point towards the player

    -- Wait for a short amount of time before updating again
    wait(0.1)
end

-- Destroy the missile when it hits the target
missile:Destroy()

In this code, tipAttachment is an Attachment that is positioned at the tip of the missile. The missileCFrame variable is the CFrame of the missile, calculated in the same way as before. To rotate the attachment to point towards the player, we create a new CFrame by multiplying the missileCFrame with CFrame.Angles(math.pi/2, 0, 0). This creates a new CFrame that rotates the attachment by 90 degrees around the missile’s

It’s kind of difficult for the missile to angle since its a model with a really weird orientation. Heres the model if your wondering:

missile_that_goes_sideways.rbxm (86.5 KB)

You can use CFroame.lookat() instead of looking towards the player ,thats how it works I think, sooooo here is the code I made or well edited

-- Get the NPC's position and the player's position
local targetPosition = Vector3.new(0, 10, 0) -- Replace with your NPC's position
local playerPosition = game.Players.LocalPlayer.Character.HumanoidRootPart.Position -- Replace with the player's position

-- Create the missile
local missile = game.ReplicatedStorage.Missile:Clone() -- Replace "Missile" with the name of your missile model
missile.Parent = workspace
missile:SetPrimaryPartCFrame(CFrame.new(Vector3.new(0, 5, 0))) -- Replace with your starting position

-- Create a BodyForce to move the missile towards the target
local bodyForce = Instance.new("BodyForce")
bodyForce.Force = Vector3.new(0, 10000, 0) -- Set the force to be in the upwards direction
bodyForce.Parent = missile.PrimaryPart

-- Create a BodyVelocity to make the missile move forward
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.Velocity = Vector3.new(0, 0, 100) -- Set the initial velocity to be in the forward direction
bodyVelocity.MaxForce = Vector3.new(100000, 100000, 100000) -- Set the max force to be high so that the missile can accelerate quickly
bodyVelocity.Parent = missile.PrimaryPart

-- Create a loop to update the missile's velocity and force
while missile.Parent do
    -- Get the direction towards the target
    local direction = (targetPosition - missile.PrimaryPart.Position).unit

    -- Set the force to move towards the target
    bodyForce.Force = direction * 10000 -- You can adjust this force value to control the missile's speed

    -- Set the velocity to move towards the target
    bodyVelocity.Velocity = direction * 100 -- You can adjust this velocity value to control the missile's speed

    -- Orient the missile towards the player
    missile:SetPrimaryPartCFrame(CFrame.new(missile.PrimaryPart.Position, playerPosition))

    -- Wait for a short amount of time before updating again
    wait(0.1)
end

-- Destroy the missile when it hits the target
missile:Destroy()
1 Like

Since im quite confused, heres my entire function for the rocket. I don’t know why but it still does it.

local function FireRocket(target, rocket_health, rocket_speed)
	local Missile = BossAssets:WaitForChild("InfernalMissile"):Clone()
	Missile.Parent = Effects
	Missile:MoveTo(Infernal.PrimaryPart.Position + Vector3.new(0, 10, 0))
	Debris:AddItem(Missile, 250)

	local SFX = Instance.new("Sound", Effects)
	SFX.Name = "RocketFireSFX"
	SFX.SoundId = "rbxassetid://" .. 132456187
	SFX.Volume = 2
	Debris:AddItem(SFX, SFX.TimeLength)
	SFX:Play()

	Missile.Humanoid.MaxHealth = rocket_health
	Missile.Humanoid.Health = rocket_health

	local MissilePrimary = Missile.HumanoidRootPart

	local bodyForce = Instance.new("BodyForce", MissilePrimary)
	bodyForce.Force = Vector3.new(0, 10000, 0) -- Set the force to be in the upwards direction

	local bodyVelocity = Instance.new("BodyVelocity", MissilePrimary)
	bodyVelocity.Velocity = Vector3.new(0, 0, 100) -- Set the initial velocity to be in the forward direction
	bodyVelocity.MaxForce = Vector3.new(100000, 100000, 100000) -- Set the max force to be high so that the missile can accelerate quickly
	
	--local tipAttachment = Missile.HumanoidRootPart:WaitForChild("TipAttachment")
	
	task.spawn(function()
		while Missile.Humanoid.Health ~= 0 do
			local direction = (target.HumanoidRootPart.Position - MissilePrimary.Position).Unit
			bodyForce.Force = direction * 10000
			bodyVelocity.Velocity = direction * rocket_speed

			--local lookVector = (target.HumanoidRootPart.Position - MissilePrimary.Position).unit
			--local missileCFrame = CFrame.new(MissilePrimary.Position, MissilePrimary.Position + lookVector)
			--tipAttachment.CFrame = missileCFrame * CFrame.Angles(math.pi/2, 0, 0) -- Rotate the attachment to point towards the player
			
			Missile:SetPrimaryPartCFrame(CFrame.new(Missile.PrimaryPart.Position, target.HumanoidRootPart.Position))
			
			wait(0.1)
		end
	end)

	Missile.Humanoid.Died:Connect(function(hit)
		Missile:Destroy()
		local Sound = Instance.new("Sound", Effects)
		Sound.SoundId = explosiveSounds[math.random(1, #explosiveSounds)]
		Sound:Play()
		Debris:AddItem(Sound, Sound.TimeLength)
	end)

	MissilePrimary.Touched:Connect(function(Hit)
		if not InvulnerabilityFrame then
			if Hit ~= nil then
				if Players:GetPlayerFromCharacter(Hit.Parent) then
					InvulnerabilityFrame = true

					local Player = Players:GetPlayerFromCharacter(Hit.Parent)

					local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
					TargetHumanoid:TakeDamage(MissileDamage)
					FX_Remotes.Camera.SmallBump:FireAllClients()
					task.wait(1)
					InvulnerabilityFrame = false
				end
			end
		end
	end)
end

Alright, to make it more precise I would recommend to use this:

local tipAttachment = Instance.new("Attachment", Missile.PrimaryPart)
tipAttachment.Name = "TipAttachment"

This just adds an attachment to the tip of the rocket

Calculate the offset between the tip and the center

local offset = tipAttachment.WorldPosition - Missile.PrimaryPart.Position

Update the tips orientation and position inside the while loop

local direction = (target.HumanoidRootPart.Position - MissilePrimary.Position).Unit
bodyForce.Force = direction * 10000
bodyVelocity.Velocity = direction * rocket_speed

-- Calculate the new position and orientation of the tip
local newPosition = MissilePrimary.Position + offset
local newOrientation = CFrame.new(MissilePrimary.Position, target.HumanoidRootPart.Position)
tipAttachment.CFrame = newOrientation * CFrame.new(offset)

Missile:SetPrimaryPartCFrame(newOrientation)
Missile.PrimaryPart.CFrame = newOrientation * CFrame.new(offset)

This should make the missile’s tip point towards the target while the missile is flying towards it. Note that you may need to adjust the offset vector.

1 Like

I don’t know if I missed anything but I think the orientation is still broken.

	local Missile = BossAssets:WaitForChild("InfernalMissile"):Clone()
	Missile.Parent = Effects
	Missile:MoveTo(Infernal.PrimaryPart.Position + Vector3.new(0, 10, 0))
	Debris:AddItem(Missile, 250)
	
	local tipAttachment = Instance.new("Attachment", Missile.PrimaryPart)
	tipAttachment.Name = "TipAttachment"
	
	local offset = tipAttachment.WorldPosition - Missile.PrimaryPart.Position

	local SFX = Instance.new("Sound", Effects)
	SFX.Name = "RocketFireSFX"
	SFX.SoundId = "rbxassetid://" .. 132456187
	SFX.Volume = 2
	Debris:AddItem(SFX, SFX.TimeLength)
	SFX:Play()

	Missile.Humanoid.MaxHealth = rocket_health
	Missile.Humanoid.Health = rocket_health

	local MissilePrimary = Missile.HumanoidRootPart

	local bodyForce = Instance.new("BodyForce", MissilePrimary)
	bodyForce.Force = Vector3.new(0, 10000, 0) -- Set the force to be in the upwards direction

	local bodyVelocity = Instance.new("BodyVelocity", MissilePrimary)
	bodyVelocity.Velocity = Vector3.new(0, 0, 100) -- Set the initial velocity to be in the forward direction
	bodyVelocity.MaxForce = Vector3.new(100000, 100000, 100000) -- Set the max force to be high so that the missile can accelerate quickly
		
	task.spawn(function()
		while Missile.Humanoid.Health ~= 0 do
			local direction = (target.HumanoidRootPart.Position - MissilePrimary.Position).Unit
			bodyForce.Force = direction * 10000
			bodyVelocity.Velocity = direction * rocket_speed

			local newPosition = MissilePrimary.Position + offset
			local newOrientation = CFrame.new(MissilePrimary.Position, target.HumanoidRootPart.Position)
			tipAttachment.CFrame = newOrientation * CFrame.new(offset)
			

			Missile:SetPrimaryPartCFrame(newOrientation)
			Missile.PrimaryPart.CFrame = newOrientation * CFrame.new(offset)
			
			wait(0.1)
		end
	end)

	Missile.Humanoid.Died:Connect(function(hit)
		Missile:Destroy()
		local Sound = Instance.new("Sound", Effects)
		Sound.SoundId = explosiveSounds[math.random(1, #explosiveSounds)]
		Sound:Play()
		Debris:AddItem(Sound, Sound.TimeLength)
	end)

	MissilePrimary.Touched:Connect(function(Hit)
		if not InvulnerabilityFrame then
			if Hit ~= nil then
				if Players:GetPlayerFromCharacter(Hit.Parent) then
					InvulnerabilityFrame = true

					local Player = Players:GetPlayerFromCharacter(Hit.Parent)

					local TargetHumanoid = Hit.Parent:WaitForChild("Humanoid")
					TargetHumanoid:TakeDamage(MissileDamage)
					FX_Remotes.Camera.SmallBump:FireAllClients()
					task.wait(1)
					InvulnerabilityFrame = false
				end
			end
		end
	end)
end