HumanRootPart CFrame angle to another HumanRootPart

Im trying to make an tower defense game, but I am facing the problem that the tower is not facing the “minion” It gives the error code: “Unable to cast Vector3 to float”

This is the code:

local idle = script.Idle
local attack = script.Attack

local enabled = false

local loadedIdle = script.Parent.Humanoid:LoadAnimation(idle):Play()

while true do
	wait()
	
	if enabled == false then
		enabled = true
		
		local attacked = false
		
		for _, units in pairs(workspace.TD.Minions:GetChildren()) do
			local distance = (units.HumanoidRootPart.Position - script.Parent.HumanoidRootPart.Position).Magnitude
			if distance < 15 and attacked == false then 
				attacked = true
				
				script.Parent.HumanoidRootPart.CFrame = CFrame.Angles(0, units.HumanoidRootPart.Position, 0) -- problem here
				
				print("attack")
			end
		end
		
		wait(1)
		enabled = false
	end
end

does anyone know how to fix this?

1 Like

is this script inside of the npc?

script.Parent.HumanoidRootPart.CFrame = CFrame.Angles(0, units.HumanoidRootPart.Position.Y, 0)

You were attempting to pass a Vector3 value as the 2nd argument to “CFrame.Angles”, you can only pass number values to the function “CFrame.Angles()”. I’ve instead opted to use the Y component of the position of the “HumanoidRootPart” (which is a number).

hm that seemed to kind of worked but there still is a problem as you can see in the video.

I have added some different code aswell because else the tower would teleport to the spawnpoint for some reason

these are the codes,

local idle = script.Idle
local attack = script.Attack
local damage = script.Parent.Stats.Damage

local enabled = false

local loadedIdle = script.Parent.Humanoid:LoadAnimation(idle)
loadedIdle:Play()

local loadedAttack = script.Parent.Humanoid:LoadAnimation(attack)

while true do
	wait()

	if enabled == false then
		enabled = true

		local attacked = false

		for _, units in pairs(workspace.TD.Minions:GetChildren()) do
			local distance = (units.HumanoidRootPart.Position - script.Parent.HumanoidRootPart.Position).Magnitude
			if distance < 10 and attacked == false then 
				while distance < 10 and attacked == false do
					script.Parent.HumanoidRootPart.CFrame = CFrame.Angles(0, units.HumanoidRootPart.Position.Y, 0)
					script.Parent.HumanoidRootPart.Position = script.Parent:WaitForChild("Originpart").Position
					attacked = true
					loadedIdle:Stop()
					loadedAttack:Play()



					units.Humanoid.Health = units.Humanoid.Health - damage.Value
					units.Humanoid.Died:Connect(function()
						script.Parent.HumanoidRootPart.CFrame = CFrame.Angles(0, units.HumanoidRootPart.Position.Y, 0)
						script.Parent.HumanoidRootPart.Position = script.Parent:WaitForChild("Originpart").Position
						units:Destroy()
					end)
					wait(.1)
					print("attack")

				end
				loadedAttack:Stop()
				loadedIdle:Play()
			end
		end
	end

	enabled = false
end
remote.OnServerEvent:Connect(function(Player, value, value2, value3)
	if value == "Place" then
		local tower = game:GetService("ReplicatedStorage").Towers[Player[value2].Value]:Clone()
		tower.Indicator:Destroy()
		tower.HumanoidRootPart.BodyPosition:Destroy()
		tower.HumanoidRootPart.Position = value3 + Vector3.new(0, -0.5, 0)
		tower.HumanoidRootPart.Anchored = true
		tower.Parent = workspace
		local originpart = Instance.new("Part", tower)
		originpart.Name = "Originpart"
		originpart.CanCollide = false
		originpart.Anchored = true
		originpart.Transparency = 1
		originpart.Position = value3 + Vector3.new(0, -0.5, 0)
end
end)

Any other issues will be with the values you’ve used, I was just fixing the error.

hey, the issue can be solved REALLY easily. I use this all the time in my Camera scripts.
CFrame can be set to CFrame = CFrame.new(OurTowerPosition, PointWhereOurTowerLooks)

This way you dont need to use angles (you didnt even calculate one via DotProduct so your CFrame.Angles is doomed to failure) and your Tower shouldnt teleport (note, I didnt look at the second code so the issue could be smth else)

So just set the “PointWhereOurTowerLooks” to the EnemyPosition. Actually PS. instead of EnemyPosition, use the Vector3.new(EnemyPos.X, towerPos.Y, EnemyPos.Z) so your tower wont look upwards or downwards

1 Like

It’s best if you do:

script.Parent.HumanoidRootPart.CFrame = CFrame.new(script.Parent.HumanoidRootPart.Position, units.HumanoidRootPart.Position)

As @Onebeets mentioend.

2 Likes

This is very simple.

What you need to do is give the tower a new CFrame.

HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.Position, minion position)

The second argument makes the part face that position.

Note: The positions NEEDS to be a Vector3 position, and I recommend the minion position to be the minions HumanoidRootPart position.

If this helped please mark it as the solution!

1 Like

Yes that worked perfectly thank you!

1 Like

You’re welcome, I’m new to Roblox developing (and Roblox) so this is very flattering!

1 Like