Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How Do I Make A Model Of A NPC Look At The Player Constantly?

Hi I have an NPC which is basically going to be an AI. I made it where it can shoot at players which is great but I want to make it look at the players while its shooting them since right now he is stationary. How do I make him rotate at me?

2 comments

0

Well, I know this was already solved but I have a simple way. make a head and put a script into it. after that you want to put this in the script:                                                           bin = script.Parent function move(target) local dir = (target.Position - bin.Position).unit local spawnPos = bin.Position local pos = spawnPos + (dir * 1) bin:findFirstChild("BodyGyro").cfra

0

Well to make the entire thing rotate I have a script that makes it so if the npc is anchored only the head moves. but I found that If I actually made it unanchored the entire thing would look at you! Ill post the script

2 answers

✓ Accepted answer

keep setting the cframe of your npc's torso to face the player.

This is some sample code:

NPC:SetPrimaryPartCFrame(CFrame.new(NPC.PrimaryPart.Position,Player.Torso.Position))

**EDIT: Fixed it. Should now move the whole NPC.

4 comments

0

When I do this only the torso moves and not the whole NPC. So do I have to CFRAME move all the parts in the npc?

0

Ah, I forgot, you have to use model:SetPrimaryPartCFrame(). Updated my code.

0

What's the primary part. It's going to index a nil value

0

NVM Fixed it TYSM

This is by no means, "The Best Way". This is simply my way.

I'm be using a eye as representation for this tutorial. You should easily be able to apply this information to your situation.

Before continuing, my method doesn't use tables. This is a bit weird, and it might be able to be done better by using tables, but this was how I did it at the time.

First.

I'll be using a body gyro for this tutorial. Body Gyros are very useful and will help with our problem a lot, and they're much smoother. So first,

Let's define some variables,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")-- BG Stands for Body Gyro.
Just defining variables

Second,

I'm going to use a while loop to look through the players and get their torsos. So second,

Setup a while loop,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	--Code later
end
You can use a while wait() do, with the wait, to simulate the same as putting the wait somewhere inside the loop.

Third,

I'm going to use a ipairs loop to iterate through the players. So third,

iterate through the players,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	for i,v in ipairs(game.Players:GetPlayers()) do
		--Code Later
	end
end
In our code later, we have a new variable called "v" that represents the player at the moment.

Fourth,

Now we need to get the character and the torso of the player. So fourth,

Get the character and torso,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local Torso = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
	end
end
Get the torso and character.

Fifth,

Now for the fun part! Lets make the eye face the direction of the player's torso! This is very easy if we use the body gyro! So fourth we,

Use the body gyro!

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local Torso = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end

Roblox wiki on Bodygyro.

Cool! This actually works now, but only for one person, and it doesn't check how far the player is from the eye. Here's a representation of it working.

Now we move onto my weird way of solving this. First, I make two new variables inside the ipairs loop,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso-- Main Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")-- T stands for Torso.
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end
Added two new variables for manipulation later. Math.huge basically returns infinity.

Now I did an if statement to check if I should me the new torso the main torso by checking its distance from the eye compared to the others,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso--Main Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		local Mag = (T.Position - eye.Position).Magnitude
		if Mag < num then-- Check to see if the new number is the new smallest number
			num = Mag-- if it is, it changes the number.
			Torso = T
		end
	end
end
Picks the lowest distance torso from the eye to be the main torso.

Last, but not least, I set the BodyGyro to the main torso after the ipairs loop, like so,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		local Mag = (T.Position - eye.Position).Magnitude
		if Mag < num then
			num = Mag
			Torso = T
		end
	end
	if Torso and num < 40 then-- the 40 is the field of view the eye has
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end
Simple if statement

But this still allows the eye to see you through walls and objects. The easiest way of fixing this is to use raycasting.

First, lets make our Ray,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		local Mag = (T.Position - eye.Position).Magnitude
		if Mag < num then
			local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)-- Might change the -500 to 500.
			num = Mag
			Torso = T
		end
	end
	if Torso and num < 40 then
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end
Sometimes the ray will fire backwards. If this happens, switch the negative to a positive.

Now we can choose what we want to ignore. This is easy. We're going to ignore the eye, the whatever the ray is firing from. Like so,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		local Mag = (T.Position - eye.Position).Magnitude
		if Mag < num then
			local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)
			local ignore = script.Parent--Ingnore
			num = Mag
			Torso = T
		end
	end
	if Torso and num < 40 then
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end
Just defining ignore.

Now we can get what the ray hit by doing,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		local Mag = (T.Position - eye.Position).Magnitude
		if Mag < num then
			local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)
			local ignore = script.Parent
			local hit = workspace:FindPartOnRay(ray, ignore)-- What the ray hit.
			num = Mag
			Torso = T
		end
	end
	if Torso and num < 40 then
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end
Blah blah

Now all we have to do is check if what the ray hit is a descendant of the player's character. We can do this by using the IsDescendantOf function, like so,

local eye = script.Parent
local BG = script.Parent:WaitForChild("BodyGyro")
while wait() do
	local Torso
	local num = math.huge
	for i,v in ipairs(game.Players:GetPlayers()) do
		local char = v.Character or v.CharacterAdded:wait()
		local T = char:FindFirstChild("Torso") or char:WaitForChild("Torso")
		local Mag = (T.Position - eye.Position).Magnitude
		if Mag < num then
			local ray = Ray.new(eye.Position, (eye.Position - T.Position).unit * -500)
			local ignore = script.Parent
			local hit = workspace:FindPartOnRay(ray, ignore)
			if hit:IsDescendantOf(char) then
				num = Mag
				Torso = T
			end
		end
	end
	if Torso and num < 40 then
		BG.CFrame = CFrame.new(eye.Position, Torso.Position)
	end
end
Checks for descendant or whatever.

And that's it!

Here's a demo of this working.

Good Luck!

If I helped, don't forget to accept my answer, it helps a lot.

2 comments

0

Just put the BodyGyro in the primary part and this should work.

0

Way to complex my guy.

This discussion is preserved as it was. New answers, comments, and votes are closed.