I have an enemy NPC that uses Humanoid:MoveTo() and checks the magnitude of the distance between it and the Player. However, once the Player “rests” at a checkpoint, the enemy NPC is teleported to it’s spawn position via PivotTo(). And after this happens, the movement becomes messed up, when the NPC is out of reach for attack, it simply falls over repeatedly, and when it approaches close enough, it will sort of turn and walk back a stud before attacking since it initially gets too close. I’ve provided a video along with the enemy ai code.
function getPlayer()
print("tatakae!")
for _, v in pairs(workspace:GetChildren()) do
if v:FindFirstChild("Self") then
--print("Player found")
character = v
enemyHumanoid:ChangeState(Enum.HumanoidStateType.Physics)
enemyHumanoid:ChangeState(Enum.HumanoidStateType.Running)
chasePlayer()
else
--print("Self not found")
end
end
end
function attackPlayer()
if not death then
local damage = false
local weapon = enemy["Right Arm"].WeaponMesh
wait()
if not death then
for i,v in pairs(enemyAnimator:GetPlayingAnimationTracks()) do
v:Stop()
end
end
local Hitbox = RaycastHitbox.new(weapon)
Hitbox.OnHit:Connect(function(hit, humanoid)
if not humanoid.Parent:FindFirstChild("Enemy") and not workspace.ReadableValues.iFrame.Value then
humanoid:TakeDamage(15)
end
end)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {enemy, workspace.Baseplate}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local setYVector = enemyRoot.CFrame.LookVector.Unit.Y -- Ensures when the ray is cast, the Y coordinate is not changed due to the moving root
local moveVector = enemyRoot.CFrame.LookVector * 0.08
local Workspace = game:GetService("Workspace")
local connection = run.Heartbeat:Connect(function()
local rayOrigin = enemyRoot.Position
local rayVector = Vector3.new(enemyRoot.CFrame.LookVector.Unit.X, setYVector, enemyRoot.CFrame.LookVector.Unit.Z)
local rayDirection = rayVector * 4
local rayResult = Workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if damage and rayResult == nil and not death then
local dir = enemyRoot.CFrame.LookVector
local goal = {}
goal.CFrame = CFrame.new(enemyRoot.Position,character:WaitForChild("HumanoidRootPart").Position)
local tweenInfo = TweenInfo.new(.5)
local tween = game:GetService("TweenService"):Create(enemyRoot, tweenInfo, goal)
tween:Play()
enemyRoot.CFrame += dir * 0.1
end
end)
if not death then
enemy.HumanoidRootPart.Anchored = true
light1Anim:Play()
end
local function enableDamage()
local pitch = (math.random(8,12)*0.1)
weapon.swoosh.PlaybackSpeed = pitch
weapon.swoosh:Play()
damage = true
Hitbox:HitStart()
end
local function disableDamage()
damage = false
Hitbox:HitStop()
end
light1Anim:GetMarkerReachedSignal("damage"):Connect(function()
enableDamage()
end)
light1Anim:GetMarkerReachedSignal("noDamage"):Connect(function()
disableDamage()
end)
light2Anim:GetMarkerReachedSignal("damage"):Connect(function()
enableDamage()
end)
light2Anim:GetMarkerReachedSignal("noDamage"):Connect(function()
disableDamage()
end)
light3Anim:GetMarkerReachedSignal("damage"):Connect(function()
enableDamage()
end)
light3Anim:GetMarkerReachedSignal("noDamage"):Connect(function()
disableDamage()
end)
local function endAttack()
--print("ender bender")
connection:Disconnect()
enemy.HumanoidRootPart.Anchored = false
enemyHumanoid.WalkSpeed = 16
isAttacking = false
endAttackEvent:Fire()
end
local stopConnect1 = light1Anim.Stopped:Connect(endAttack)
local stopConnect2 = light2Anim.Stopped:Connect(endAttack)
light3Anim.Stopped:Connect(endAttack)
light1Anim:GetMarkerReachedSignal("canCombo"):Connect(function()
local distance = (character.Torso.Position - enemyRoot.Position).Magnitude
if distance <= 8 then
stopConnect1:Disconnect()
--light1Anim:Stop()
task.wait(.75)
light2Anim:Play()
end
end)
light2Anim:GetMarkerReachedSignal("canCombo"):Connect(function()
local distance = (character.Torso.Position - enemyRoot.Position).Magnitude
if distance <= 8 then
stopConnect2:Disconnect()
--light2Anim:Stop()
task.wait(.75)
light3Anim:Play()
end
end)
end
return
end
function chasePlayer()
--local region = script.Parent.Parent.AttackRegion
if character ~= nil then
local regionSize = Vector3.new(4,5,4)
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = {character}
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")
local part = Instance.new("Part", script.Parent.Parent)
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")
local function repeatDetection()
local heartbeatConnection
heartbeatConnection = RunService.Heartbeat:Connect(function()
if isAttacking or hurt or death then
heartbeatConnection:Disconnect()
return
end
--local regionCenter = CFrame.new(enemyRoot.Position + Vector3.new(0,0,-1))
local distance = (character.Torso.Position - enemyRoot.Position).Magnitude
--local regionDetect = workspace:GetPartBoundsInBox(regionCenter, regionSize, params)
--part.Anchored = true
--part.CanCollide = false
--part.Transparency = 0.7
--part.BrickColor = BrickColor.new("Really red")
--part.Size = regionSize
--part.CFrame = regionCenter
local rayOrigin = script.Parent.Parent.Torso.CFrame.Position
local rayDirection = enemyRoot.CFrame.LookVector.Unit * 7
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 > 8 then
print("still casting")
p.BrickColor = BrickColor.new("Really blue")
enemyHumanoid:MoveTo(torso.CFrame.Position)
else
print("cast finished")
p.BrickColor = BrickColor.new("Lime green")
enemyHumanoid.WalkSpeed = 0
enemyHumanoid:MoveTo(enemyRoot.CFrame.Position)
isAttacking = true
attackPlayer()
--print(isAttacking)
end
end
end)
end
endAttackEvent.Event:Connect(function()
wait(0.1)
repeatDetection()
end)
repeatDetection()
end
else
--print("Character not found")
end
end