Humanoid Target System Homing Missile problem

Hi guys, I got a problem between connecting a target system with a homing missile.

You see, I been struggling by finding the humanoid of my target lock on system (A Local Script in StarterGui) and implementing it within the missile system (A built in script within the part).

I have tried using remote events to connect the variables, but it seems since the script does not support canvasgroup, which makes me kinda stuck now

Heres the local script for target lock on system

local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local missile = game.Workspace.missile:FindFirstChild("lockonthing")

local camModule = require(script:WaitForChild("Camera"))
local camMode = "Freecam"

local remotefold = RS.Remotes
local remote = remotefold.AimAtTarget



local main = game.StarterGui.ScreenGui.Main
local targetFrame = main.Target

UIS.InputBegan:Connect(function(input, processed)
	if processed then return end

	if input.KeyCode == Enum.KeyCode.E then
		if camMode == "Freecam" then
			camMode = "LockNearest"
			camModule.LockNearest(targetFrame)
			remote:FireServer(missile)
		else
			camMode = "Freecam"
			camModule.Freecam(targetFrame)
		end
	end
end)

here’s the script for the homing missile

-- Lock on variables
local missile = script.Parent
local targetFrame
local main
local v = 100 -- velocity
local sd = 2.5
local vf = missile.VectorForce

-- Remote event variables
local RS = game:GetService("ReplicatedStorage")
local remotefold = RS.Remotes
local remote = remotefold.AimAtTarget
local localscriptlockonhumanoid = game.StarterGui.ScreenGui:WaitForChild("LocalScript")
local thescriptitself = missile.lockonthing

vf.Force = Vector3.new(0, workspace.Gravity * missile:GetMass(), 0)

remote.OnServerEvent:Connect(function(thescriptitself, localscriptlockonhumanoid)
	local main = game.StarterGui.ScreenGui.Main
	local targetFrame = main.Target


local function Move(step)
	local d = (missile.Position - targetFrame.Position).Magnitude -- d is distance
	if d > sd then
		missile.CFrame = missile.CFrame:Lerp(targetFrame.CFrame, step * v/d)
		missile.CFrame = CFrame.new(missile.Position, targetFrame.Position) * CFrame.Angles(math.rad(0), math.rad(90), math.rad(0))
	end
end

game:GetService("RunService").Stepped:Connect(function(time, step)
	Move(step)
end)
	end)

and here’s a module script which the local script is its parent

local runService = game:GetService("RunService")
local tweenService = game:GetService("TweenService")
local userInputService = game:GetService("UserInputService")

local camera = {}

camera.LockOnInfo = {
	Range = 100, -- The range of the lock on
	Speed = 20, -- The speed of which the lock on camera is moving
	Offset = Vector3.new(3, 4, -9), -- The camera offset when using lock on
	LockOnPlayers = true, -- Lock on player in the world
	RequiresLineOfSight = true,-- If the characer needs line of sight with target to use lock on
	ObstructionBreakTime = 0.5, -- The time without line of sight that takes to exit the lock on
	SwitchDebounce = 0.3, -- The debounce or cooldown of switching targets
	SwitchSens = 5, -- How sensetive the switching should be
	SwitchRange = 50, -- How far away you can switch target
}

local target 
local lookConnection, healthConnection

function camera.GetTargetsInRange(character)
	local targets = {}

	for i, part in pairs(workspace:GetPartBoundsInRadius(character.HumanoidRootPart.Position, camera.LockOnInfo.Range)) do
		if part:IsA("BasePart") and part.Parent:FindFirstChild("Humanoid") then
			if game.Players:GetPlayerFromCharacter(part.Parent) then
				if camera.LockOnInfo.LockOnPlayers == true then
					if not table.find(targets, part.Parent) then
						table.insert(targets, part.Parent)
					end 
				end
			else
				if not table.find(targets, part.Parent) then
					table.insert(targets, part.Parent)
				end 
			end
		end
	end

	return targets
end

function camera.GetTargetsClosestCrosshair(character, cam)
	local targets = camera.GetTargetsInRange(character)

	local nearest = 1
	local target = nil

	for i, char in targets do
		if char and char ~= character then
			local distance = (char.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude

			local cameraToTarget = (char.HumanoidRootPart.Position - cam.CFrame.Position).Unit
			local cameraLook = cam.CFrame.LookVector

			local dotProduct = cameraToTarget:Dot(cameraLook)
			local difference = math.abs(1 - dotProduct)

			if distance < camera.LockOnInfo.Range and dotProduct > 0.5 then
				if difference < nearest then
					nearest = difference
					target = char
				end
			end
		end
	end

	local rightTarget = nil
	local leftTarget = nil

	local nearestRight = camera.LockOnInfo.SwitchRange
	local nearestLeft = -camera.LockOnInfo.SwitchRange

	for i, char in targets do
		if char and target and char ~= target then
			local distance = character.HumanoidRootPart.CFrame:ToObjectSpace(char.HumanoidRootPart.CFrame)      
			if distance.Z < 0 then
				if distance.X > 0 then
					if nearestRight then
						if distance.X < nearestRight then
							nearestRight = distance.X
							rightTarget = char
						end
					else
						nearestRight = distance.X
						rightTarget = char      
					end
				elseif distance.X < 0 then
					if nearestLeft then
						if distance.X > nearestLeft then
							nearestLeft = distance.X
							leftTarget = char
						end
					else
						nearestLeft = distance.X
						leftTarget = char       
					end

				end
			end
		end
	end

	return target, rightTarget, leftTarget
end

function camera.IsTargetInView(character, target)
	local excludedCharacters = camera.GetTargetsInRange(character)
	table.remove(excludedCharacters, table.find(excludedCharacters, target))

	local rayParams = RaycastParams.new()
	rayParams.FilterType = Enum.RaycastFilterType.Exclude
	rayParams.FilterDescendantsInstances = excludedCharacters

	local origin = character.HumanoidRootPart.Position
	local direction = (target.HumanoidRootPart.Position - origin).Unit

	local ray = workspace:Raycast(origin, direction * camera.LockOnInfo.Range, rayParams)

	if ray then
		if ray.Instance.Parent == target then
			return true
		end
	end

	return false
end

function camera.SelectTarget(target, newTarget)
	if target then
		local selection = target:FindFirstChild("Selection")

		if selection then
			selection:Destroy()
		end
	end

	if newTarget then
		local newSelection = Instance.new("Highlight", newTarget)
		newSelection.FillTransparency = 1
		newSelection.FillColor = Color3.fromRGB(255, 255, 255)
		newSelection.OutlineTransparency = 0
		newSelection.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
		newSelection.Name = "Selection"
	end
end

function camera.SetLocalTransparency(character, transparency) -- Used to prevent the character from being invisible when locking if first person
	for i, v in pairs(character:GetDescendants()) do
		if v:IsA("BasePart") and v.Name ~= "HumanoidRootPart" then
			v.LocalTransparencyModifier = transparency
		end
	end
end

function camera.LockNearest(targetFrame)
	local cam = workspace.CurrentCamera

	local player = game.Players.LocalPlayer
	local mouse = player:GetMouse()

	local character = player.Character

	if not character then return end

	local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
	local humanoid = character:WaitForChild("Humanoid")

	target = camera.GetTargetsClosestCrosshair(character, cam)
	camera.SelectTarget(nil, target)

	if target and target:FindFirstChild("Humanoid") and camera.IsTargetInView(character, target) then   
		camera.SetLocalTransparency(character, 0)

		cam.CameraType = Enum.CameraType.Scriptable

		userInputService.MouseIconEnabled = false
		userInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition

		targetFrame.TargetLabel.Text = target.Name
		targetFrame.Health.Size = UDim2.new(target.Humanoid.Health/target.Humanoid.MaxHealth, 0, 1, 0)

		healthConnection = target.Humanoid.Changed:Connect(function()
			if target.Humanoid then
				targetFrame.Health:TweenSize(UDim2.new(target.Humanoid.Health/target.Humanoid.MaxHealth, 0, 1, 0))
			end
		end)

		tweenService:Create(targetFrame, TweenInfo.new(0.2), {GroupTransparency = 0}):Play()
	else
		camera.Freecam(targetFrame)
		lookConnection:Disconnect()
		return
	end

	local lastObstructed = nil
	local lastTime = tick()
	local lastDelta = 0

	lookConnection = runService.RenderStepped:Connect(function(dt)
		dt = (lastDelta + dt)/2 -- Smooth the delta to prevent fps drops
		lastDelta = dt

		if not target then 
			camera.Freecam(targetFrame)
			return 
		end

		local distance = (target.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude

		local requiresLineOfSight = camera.LockOnInfo.RequiresLineOfSight
		local hasLineOfSight = camera.IsTargetInView(character, target)
		local lineOfSight = (hasLineOfSight and requiresLineOfSight) or not requiresLineOfSight -- Check for line of sight if required

		if not lineOfSight then
			if not lastObstructed then
				lastObstructed = tick()
			elseif tick() - lastObstructed > 1 then
				lastObstructed = nil
				camera.Freecam(targetFrame)
				lookConnection:Disconnect()
				return
			end
		else
			lastObstructed = nil
		end

		if (distance < camera.LockOnInfo.Range and target.Humanoid.Health > 0) then
			local targetPosition = Vector3.new(target.HumanoidRootPart.Position.X, character.HumanoidRootPart.Position.Y, target.HumanoidRootPart.Position.Z)
			local newCFrame = CFrame.lookAt(character.HumanoidRootPart.Position, targetPosition, character.HumanoidRootPart.CFrame.UpVector)
			character.HumanoidRootPart.CFrame = newCFrame   

			local offsetX = humanoidRootPart.CFrame.RightVector * camera.LockOnInfo.Offset.X
			local offsetY = humanoidRootPart.CFrame.UpVector * camera.LockOnInfo.Offset.Y
			local offsetZ = humanoidRootPart.CFrame.LookVector * camera.LockOnInfo.Offset.Z

			local offset = offsetX + offsetY + offsetZ
			local cameraPosition = humanoidRootPart.Position + offset

			local targetCFrame = CFrame.lookAt(cameraPosition, target.HumanoidRootPart.Position, humanoidRootPart.CFrame.UpVector)
			cam.CFrame = cam.CFrame:Lerp(targetCFrame, dt * camera.LockOnInfo.Speed)

			if tick() - lastTime > camera.LockOnInfo.SwitchDebounce then
				local mouseDeltaX = userInputService:GetMouseDelta().X

				if mouseDeltaX > camera.LockOnInfo.SwitchSens or mouseDeltaX < -camera.LockOnInfo.SwitchSens then
					local _, rightTarget, leftTarget = camera.GetTargetsClosestCrosshair(character, cam)

					if mouseDeltaX > camera.LockOnInfo.SwitchSens and rightTarget and camera.IsTargetInView(character, rightTarget) then -- Determine the direction of the mouse and switching target accordingly
						camera.SelectTarget(target, rightTarget)
						target = rightTarget
					elseif mouseDeltaX < -camera.LockOnInfo.SwitchSens and leftTarget and camera.IsTargetInView(character, leftTarget)  then
						camera.SelectTarget(target, leftTarget)
						target = leftTarget
					end
				end

				lastTime = tick()
			end
		else
			camera.Freecam(targetFrame)
		end
	end)

	local deathConnection
	deathConnection = humanoid.Died:Connect(function()
		deathConnection:Disconnect()
		camera.Freecam(targetFrame)
	end)

	return target
end

function camera.Freecam(targetFrame)
	lookConnection:Disconnect()
	healthConnection:Disconnect()

	camera.SelectTarget(target, nil)

	userInputService.MouseIconEnabled = true
	userInputService.MouseBehavior = Enum.MouseBehavior.Default

	targetFrame.TargetLabel.Text = ""
	targetFrame.Health.Size = UDim2.new(1, 0, 1, 0)

	tweenService:Create(targetFrame, TweenInfo.new(0.2), {GroupTransparency = 1}):Play()

	local cam = workspace.CurrentCamera
	cam.CameraType = Enum.CameraType.Custom
end

return camera

both the local and module is from teletacos tutorial/explanation on a target lock system
here’s the link if you wanna watch it: https://www.youtube.com/watch?v=mu3HfDjQfwE

and heres the error I’ve been getting with it currently

you guys got any idea whats wrong?

1 Like