Enemy RayCasting RayOrigin Issue; RayOrigin somehow changes?

I’m creating a simple enemy AI that uses Humanoid:MoveTo() and RayCasting to determine if the enemy is close enough to attack. The issue I’m encountering is that the enemy’s RayOrigin will sometimes “clip through”, and originate from a few studs behind the HumanoidRootPart of the enemy (when it should just be the HumanoidRootPart). I’ve tried seeing if the RayOrigin actually changes, but it is still the same despite this. I’ve provided a video to show the issue, and the code that handles chasing the Player

function chasePlayer()
	if character ~= nil then
		local stop = false
		local humanoid = character:FindFirstChild("Humanoid")
		local torso = character:FindFirstChild("Torso")
		local root = character:FindFirstChild("HumanoidRootPart")
		
		if humanoid ~= nil and torso ~= nil and humanoid.Health > 0 then
			if light1Anim.IsPlaying then
				light1Anim:Stop()
			end
			
			local p = Instance.new("Part", workspace)
			p.Anchored = true
			p.CanCollide = false
			p.Name = "RayVisual"
			p.Material = Enum.Material.Neon
			p.BrickColor = BrickColor.new("Really blue")
			
			while not isAttacking and not hurt and not death do
				local raycastParams = RaycastParams.new()
				raycastParams.FilterDescendantsInstances = {character}
				raycastParams.FilterType = Enum.RaycastFilterType.Include
				local Workspace = game:GetService("Workspace")
				local distance = (character.Torso.Position - enemyRoot.Position).Magnitude
				local rayOrigin = enemyRoot.CFrame.Position
				local rayDirection = enemyRoot.CFrame.LookVector.Unit * 4
				local rayResult = Workspace:Raycast(rayOrigin, rayDirection, raycastParams)
				p.Size = Vector3.new(0.1, 0.1, distance)
				p.CFrame = CFrame.lookAt(rayOrigin, character.Torso.Position)*CFrame.new(0, 0, -distance/2)
				if distance < 80 then
					if not stop and rayResult == nil then
						print("still casting")
						enemyHumanoid:MoveTo(root.CFrame.Position)
					else
						print("cast finished")
						enemyHumanoid:MoveTo(enemyRoot.CFrame.Position)
						isAttacking = true
						attackPlayer()
						endAttackEvent.Event:Wait(.5)
						--print(isAttacking)
					end
				
				end
				
				wait()
			end

		end
	else
		--print("Character not found")
	end
end

It may not be a problem with the raycast itself, but perhaps with how your visualizing the raycast.

Also, why not just use a basic magnitude checking?

No the same behavior replicates even without the visual. When I boot up the game, the correct behavior is there until… well, it isn’t. I provided a video of the correct behavior.

In terms of why I chose not to use Magnitude, the Magnitude method is less responsive when the Player moves towards the enemy (the Player will collide with the enemy before the enemy realizes the distance closes in), where as RayCast is immediate.

why would magnitude would be less responsive? They both would be immediate, no?

If the player is within 80 studs of the enemy, the enemy would move towards the target until it is within 4 studs of the character, and then attack the player. This would be much simpler than raycasting.

That’s what I thought too. When I tried it, it was not as responsive as the RayCast method. I can show you what I wrote for it.

function chasePlayer()
	if character ~= nil then
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {character}
		raycastParams.FilterType = Enum.RaycastFilterType.Include
		local stop = false
		local humanoid = character:FindFirstChild("Humanoid")
		local torso = character:FindFirstChild("Torso")
		local root = character:FindFirstChild("HumanoidRootPart")
		
		if humanoid ~= nil and torso ~= nil and humanoid.Health > 0 then
			if light1Anim.IsPlaying then
				light1Anim:Stop()
			end
			
			--local p = Instance.new("Part", workspace)
			--p.Anchored = true
			--p.CanCollide = false
			--p.Name = "Za Ray Ray"
			--p.Material = Enum.Material.Neon
			--p.BrickColor = BrickColor.new("Really blue")
			
			while not isAttacking and not hurt and not death do
				
				local distance = (character.Torso.Position - enemyRoot.Position).Magnitude
				--local rayOrigin = enemyRoot.CFrame.Position
				--local rayDirection = enemyRoot.CFrame.LookVector.Unit * 4
				--local rayResult = Workspace:Raycast(rayOrigin, rayDirection, raycastParams)
				--p.Size = Vector3.new(0.1, 0.1, distance)
				--p.CFrame = CFrame.lookAt(rayOrigin, character.Torso.Position)*CFrame.new(0, 0, -distance/2)
				if distance < 80 then
					if not stop and distance >= 4 then
						print("still casting")
						enemyHumanoid:MoveTo(root.CFrame.Position)
					else
						print("cast finished")
						enemyHumanoid:MoveTo(enemyRoot.CFrame.Position)
						isAttacking = true
						attackPlayer()
						endAttackEvent.Event:Wait(.5)
						--print(isAttacking)
					end
				
				end
				
				wait()
			end

		end
	else
		--print("Character not found")
	end
end

If it helps, this issue only starts happening after a certain mechanic where the player “rests” at a checkpoint, which resets all NPCs by teleporting them to their spawn point via changing the HumanoidRootPart CFrame