so i have an AI using an attack to damage the player, with it spawning a hitbox to make sure it does damage. however, the problem is that when it does it again, even after destroying the previous instance, it spawns the previous amount + 1. not sure if this is a bug but I am seriously confused.
local myCharacter = script.Parent
local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local attack = script.Parent:WaitForChild("Attack")
local attackAnim = myHuman:LoadAnimation(attack)
attackAnim.Priority = Enum.AnimationPriority.Action
local AB1 = script.Parent:WaitForChild("AB1")
local ab1Anim = myHuman:LoadAnimation(AB1)
ab1Anim.Priority = Enum.AnimationPriority.Action
local attackCooldown = false
--services
local rs = game:GetService("ReplicatedStorage")
local clone = script.Parent:Clone()
function walkRandomly()
local xRand = math.random(-50,50)
local zRand = math.random(-50,50)
local goal = myRoot.Position + Vector3.new(xRand, 0, zRand)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position, goal)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(.1)
if not timeOut then
print("Got Stuck")
myHuman.Jump = true
walkRandomly()
end
end
else
print("Path Failed")
wait(1)
walkRandomly()
end
end
function findPath(target)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position, target.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(.1)
if not timeOut then
myHuman.Jump = true
print("Path too long!")
findPath(target)
break
end
if checkSight(target) then
repeat
print("moving directly to the target")
myHuman:MoveTo(target.Position)
local moveChosen = math.random(1,2)
--local moveChosen = 1
print(moveChosen)
if moveChosen == 1 then
attack(target)
elseif moveChosen == 2 then
print(target)
ab1(target)
end
wait(.1)
if target == nil then
break
elseif target.Parent == nil then
break
end
until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
break
end
if (myRoot.Position - waypoints[1].Position).magnitude > 10 then
print("target has moved, generating new path")
findPath(target)
break
end
end
end
end
function checkSight(target)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {script.Parent}
raycastParams.IgnoreWater = true
local hit = workspace:Raycast(myRoot.Position, (target.Position - myRoot.Position).Unit * 40, raycastParams)
if hit then
--if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
print("Target Visible")
return true
--end
end
return false
end
function findTarget()
local dist = 300
local target = nil
local potentialTargets = {}
local seeTargets = {}
for i,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= script.Parent.Name then
if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
table.insert(potentialTargets, torso)
end
end
end
if #potentialTargets > 0 then
for i,v in ipairs(potentialTargets) do
if checkSight(v) then
table.insert(seeTargets, v)
elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
if #seeTargets > 0 then
dist = 200
for i,v in ipairs(seeTargets) do
if (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
return target
end
function attack(target)
if (myRoot.Position - target.Position).magnitude < 5 then
attackAnim:Play()
if target.Parent ~= nil then
target.Parent.Humanoid:TakeDamage(25)
end
wait(.8)
end
end
function died()
wait(5)
clone.Parent = workspace
game:GetService("Debris"):AddItem(script.Parent,.1)
end
myHuman.Died:Connect(died)
function main()
local target = findTarget()
if target then
myHuman.WalkSpeed = 16
findPath(target)
else
myHuman.WalkSpeed = 8
walkRandomly()
end
end
function ab1(target)
if (myRoot.Position - target.Position).magnitude < 5 then
print("move successful, target in range")
if target.Parent ~= nil then
if attackCooldown == false then
attackCooldown = true
ab1Anim:Play()
ab1Anim.Stopped:Connect(function()
local hitbox = rs:WaitForChild("Hitbox"):Clone()
hitbox.CanCollide = false
hitbox.Transparency = .6
hitbox.Color = Color3.fromRGB(170, 0, 255)
hitbox.Parent = workspace
hitbox.CFrame = script.Parent.Sword.PrimaryPart.CFrame
hitbox.Anchored = true
local count = 0
repeat
hitbox.Size = hitbox.Size + Vector3.new(4,4,4)
count = count + 1
local modelsHit = {}
hitbox.Touched:Connect(function(part)
local parentModel = part.Parent
if parentModel then
-- check to see if this model has already been hit
if modelsHit[parentModel] then
return
end
-- log this model as hit
modelsHit[parentModel] = true
if modelsHit[myCharacter] then
return
end
-- look for a humanoid
local humanoid = parentModel:FindFirstChild("Humanoid")
if humanoid then
humanoid:TakeDamage(1) -- TakeDamage to respect ForceFields
end
end
end)
wait()
until count == 4
wait(2)
hitbox:Destroy()
hitbox = nil
end)
end
end
wait(3)
attackCooldown = false
end
end
while wait(2) do
if myHuman.Health < 1 then
break
end
main()
end
I am aware that there is a script that loops and chooses the ability, but when its not in range, it should just end itself as shown in the attack() function.
video:
it gets less transparent the more he uses it.