How would I make a part move closer to a player

Hello, I am trying to make a script that makes a part move closer to a player if they aren’t looking at it. But I don’t know how to achieve this. I want to make it so instead of teleporting behind the player, make it instead just move closer to the player’s position

local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local part = workspace["B L A R K"]

RunService.RenderStepped:Connect(function()
	local pos,canSee = workspace.CurrentCamera:WorldToViewportPoint(part.Position)
	if not canSee and player.Character.Humanoid.Health ~= 0 then
		part.CFrame = CFrame.new(part.CFrame.LookVector * 1) -- I want the part to move closer to the player 
		wait(0.05)
		if (part.Position - player.Character.HumanoidRootPart.Position).Magnitude < 3 then
			player.Character:BreakJoints()
		end
	end
end)

The code above doesn’t work and just puts the part at the origin

You could use FOV to determine whether the player is looking at the object, this video could help:

The part moving to the player is then relatively simple. You could either do it mathematically or through a tween.

edit:
I reread your post and I realised you were probably talking about if the player is using the camera to look at a part, in which case the method I suggested wouldn’t work really.

Having said that you could do what you’re doing but use this instead and then change the position by the adjustment:

local DURATION = 10
RunService.RenderStepped:Connect(function(delta)
  local Adjustmentx = Target.Position.x*(delta/DURATION)
  local Adjustmentz = Target.Position.z*(delta/DURATION)
  local Adjustmenty = Target.Position.y*(delta/DURATION)
  if not canSee and player.Character.Humanoid.Health ~= 0 then
    Part.CFrame = CFrame.new(Part.Position.x + Adjustmentx, Part.Position.y + Adjustmenty, Part.Position.z + Adjustmentz)
2 Likes

A better solution to if the player sees the object I think would be WorldToScreenPoint
Example would be

local position, onScreen = camera:WorldToScreenPoint(part.Position)
if onScreen then
--do thing
end

This isn’t what I’m looking for. My code moves the part to the origin when I look away from it

You can easily change the previous code

local position, onScreen = camera:WorldToScreenPoint(part.Position)
if not onScreen then
--do thing
end

if you want to make the part go away afterwards but I’m not sure fully how you should make it go back to the origin

I want my part to move to the player when it’s not looking at it. I know how to check if the part is already on screen

I don’t think OP is asking about how to check if something is on screen or not (although I’ll also throw my own answer in here as well :slight_smile:)

OP the easiest way is to make your part a “zombie” that uses a Humanoid to walk towards the player with Humanoid | Roblox Creator Documentation. There are lots of resources for how to make zombies like this—the only change you’d make is to stop the zombie when the player looks at them, and start them when they look away.

Alternatively, use something like RocketPropulsion | Roblox Creator Documentation to make the part float towards the player easily, or a similar object.

If you really must use CFrame you can.

Also, don’t put a wait inside a RenderStepped.

1 Like

I have tried using RocketPropulsion and for some reason it just doesn’t make the part move at all.
Although I will try your “Zombie” idea.

RocketPropulsion needs to be instructed to activate with a function

Rocket:Fire()

you can also abort it with

Rocket:Abort()

Of course if this isn’t what you want it to be then I’d recommend trying the Zombie second

So I have tried using the zombie idea but it only kills the player if they are within 3 studs.

local RunService = game:GetService("RunService")
local player = game.Players.LocalPlayer
local part = workspace["B L A R K"]

RunService.RenderStepped:Connect(function()
	local pos,canSee = workspace.CurrentCamera:WorldToViewportPoint(part.HumanoidRootPart.Position)
	if not canSee and player.Character.Humanoid.Health ~= 0 then
		part.Humanoid:MoveTo(player.Character.HumanoidRootPart.Position)
		if (part.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).Magnitude < 3 then
			player.Character:BreakJoints()
		end
	end
end)

Edit: It doesn’t work for like 1 minute but then begins to move to the player if they are not looking at it

2 Likes

use CFrame.lookAt to make the part orientate itself towards the player. From there, you can just move the part forward.

part.CFrame = CFrame.lookAt(part.CFrame.p, player.Character.HumanoidRootPart.CFrame.p)
part.CFrame = part.CFrame * CFrame.new(0, 0, -1) --negative z is forward

If you do not want the part to rotate and just want it to move you can just remove the rotation matrices before applying it to the part.

1 Like