How do you make an npc look at you and walk backwards if you're close to them?

im trying to remake a feature from this game called “woman repellant” where the npc walks away and stares at u if u get close to it. i made the script but the lookatCF and the :MoveTo wont work together, they’ll only work if i take out one or the other.

		local function update()
			local mag = (hrp.Position - catHRP.Position).Magnitude
			local direction = (hrp.Position - catHRP.Position).Unit
			local angleinRads = math.atan2(direction.Z, direction.X)
			if mag < DISTANCE then
				local targetpos = Vector3.new(hrp.Position.X, catHRP.Position.Y, hrp.Position.Z)
				local lookatCF = CFrame.lookAt(catHRP.Position, targetpos)
				catHRP.CFrame = lookatCF
				cat_humanoid:MoveTo(catHRP.Position + direction * distToMoveBack)
				if not playing then
					runAnimTrack:Play()
					playing = true
				end
			else
				runAnimTrack:Stop()
				playing = false
			end
		end
		connection = rs.Stepped:Connect(update)

woman repellant:

1 Like

i sorta acheived this by spamming lookat and walk to point as fast as i could right next to eachother

2 Likes

For walking, I would try using the :Move() method for your NPCs’ Humanoid. It will move the Humanoid in a given Vector3. It has two arguments to pass in,

local vec3 = Vector3.new(-1 ,0, 0)
Humanoid:Move(vec3, true) -- First parameter is the Vector3, and the second parameter is if you want the humanoid to move relative to their camera.

If you don’t want to use Vector3 , then set the second parameter to true. This will make the humanoid walk relative to their camera, which is their CFrame.

Hope this helps.

1 Like

they also need the npc to look at you, and editing the CFrame of a humanoid’s character will stop their moving values

2 Likes

hey guys, thank you very much for your help. i sort of found a solution using bodygyro and that’s rotating the character through the cframe lookat and i can move it backwards. i know bodygyro is deprecated so i’ll switch it to alignorientation later.

this is the solution (somewhat, its a bit buggy sometimes):

game.Players.PlayerAdded:Connect(function(p)
	p.CharacterAdded:Connect(function(c)
		-- Variables
		local npc = workspace:FindFirstChild("catr6") -- Replace with your NPC
		local catHumanoid = npc:WaitForChild("Humanoid")
		local catHRP = npc:WaitForChild("HumanoidRootPart")
		local hrp = c:WaitForChild("HumanoidRootPart")
		local runanim = npc.run
		local runAnimTrack = catHumanoid.Animator:LoadAnimation(runanim)
		local connection = nil
		local playing = false
		
		-- Create BodyGyro to handle rotation
		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.MaxTorque = Vector3.new(0, 4000, 0)  -- Only rotate along the Y axis
		bodyGyro.P = 3000  -- Power for the gyro (rotation strength)
		bodyGyro.D = 500  -- Damping to smooth out rotation
		bodyGyro.Parent = catHRP
		
		-- Function to smoothly rotate and move backward
		local function moveAway()
			local distance = (catHRP.Position - hrp.Position).Magnitude

			-- If player is close enough
			if distance < 10 then
				-- Smoothly rotate the NPC towards the player using BodyGyro
				bodyGyro.CFrame = CFrame.lookAt(catHRP.Position, Vector3.new(hrp.Position.X, catHRP.Position.Y, hrp.Position.Z))

				-- Calculate a point 10 studs backwards and move there
				local backwardDirection = (catHRP.Position - hrp.Position).Unit * 10
				local targetPosition = catHRP.Position + backwardDirection
				catHumanoid.WalkToPoint = targetPosition
				catHumanoid.AutoRotate = false
				if not playing then
					runAnimTrack:Play()
					playing = true
					print("playing!")
				end
			else
				-- Stop the NPC if player is far
				catHumanoid.WalkToPoint = catHRP.Position
				catHumanoid.AutoRotate = true
				runAnimTrack:Stop()
				playing = false
			end
		end

		-- Connect to RunService to check player's position every frame
		game:GetService("RunService").Stepped:Connect(moveAway)

	end)
end)