- What do you want to achieve? Keep it simple and clear!
I want to make an AI system like the evade rebels.
- What’s the problem? Include screenshots/videos if possible!
The problem is that I don’t know how to do it, I know how to program it, currently the most similar script (from the toolbox) is this one:
- What solutions have you tried so far? Did you search for solutions on Developer Hub?
No.
local npc = script.Parent
------Respawn------
local clone = npc:Clone()
------Fix network issues------
while npc.HumanoidRootPart:GetNetworkOwnershipAuto() do
npc.HumanoidRootPart:SetNetworkOwner()
wait()
end
------Body Variables------
local Humanoid = npc.Humanoid
local myTorso = npc.Torso
local myHead = npc.Head
local myFace = myHead.face
local neck = myTorso.Neck
local headWeld = myTorso["Head Weld"]
local rArm = npc["Right Arm"]
local lArm = npc["Left Arm"]
local lShoulder = myTorso["Left Shoulder"]
local rShoulder = myTorso["Right Shoulder"]
local lArmWeld = myTorso["Left Arm Weld"]
local rArmWeld = myTorso["Right Arm Weld"]
local gyro = npc.HumanoidRootPart.BodyGyro
------M4 Variables------
local m4 = npc.M4
local m4Weld = m4["M4 Weld"]
local barrel = npc.Barrel
local aimer = npc.Aimer
local aimerWeld = aimer["Aimer Weld"]
local fullMag = 30
local mag = fullMag
local flash = barrel.Attachment.Flash
------Sounds------
local equipSound = m4.Equip
local fireSound = m4.Fire
local reloadSound = m4.Reload
local hurtSound = myHead.Hurt
--Animation
local reloadAnimation = Humanoid:LoadAnimation(npc.Animations.Reload)
reloadAnimation.Priority = Enum.AnimationPriority.Action
------Status------
local reloading = false
local weaponAimed = false
local weaponCool = true
local m4Equipped = false
local knifeEquipped = false
local grenadeCool = true
local currentTarget = nil
local status = "Idle"
local faces = {Idle = "http://www.roblox.com/asset/?id=23219775",
Attacking = "http://www.roblox.com/asset/?id=286688505",
Hunting = "http://www.roblox.com/asset/?id=209715003 ",
Hurt = "http://www.roblox.com/asset/?id=258192246",
Dead = "http://www.roblox.com/asset/?id=15426038"}
local gunPointedAt = nil
------Target/Ally Tracking------
local allies = {"Rescripted_Developer"}
local potentialTargets = {}
local activeAllies = {}
local team = npc.Settings.Team.Value
local attackPlayers = npc.Settings.AttackPlayers.Value
function dofunction(func,...)
local co = coroutine.wrap(func)
co(...)
end
function checkDist(part1,part2)
return (part1.Position - part2.Position).Magnitude
end
function checkSight(target)
local ray = Ray.new(barrel.Position, (target.Position - barrel.Position).Unit * 75)
local part,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
local ray2 = Ray.new(myTorso.Position, (target.Position - myTorso.Position).Unit * 75)
local part2,position2 = workspace:FindPartOnRayWithIgnoreList(ray2, {script.Parent})
if part and part2 then
if part:IsDescendantOf(target.Parent) and part2:IsDescendantOf(target.Parent) then
return true
end
end
return false
end
function checkSight2(target)
local ray = Ray.new(myHead.Position, (target.Position - myHead.Position).Unit * 75)
local part,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
local ray2 = Ray.new(myTorso.Position, (target.Position - myTorso.Position).Unit * 75)
local part2,position2 = workspace:FindPartOnRayWithIgnoreList(ray2, {script.Parent})
if part and part2 then
if part:IsDescendantOf(target.Parent) and part2:IsDescendantOf(target.Parent) then
return true
end
end
return false
end
function updateFace()
if myFace.Texture ~= faces.Dead and myFace.Texture ~= faces.Hurt then
myFace.Texture = faces[status]
end
end
function findTarget()
local dist = npc.Settings.DetectionRange.Value
local target = nil
potentialTargets = {}
local seeTargets = {}
for _,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("HumanoidRootPart") or v:FindFirstChild("Torso")
local closestdistance = math.huge
local closestcharacter = nil
if human and torso and v ~= npc then
--Check and see if they are on our team, if they are break the loop.
local targetTeam
local teammate = false
if v:FindFirstChild("Team") then
targetTeam = v.Team.Value
elseif v:FindFirstChild("Settings") and v.Settings:FindFirstChild("Team") then
targetTeam = v.Settings.Team.Value
end
if (targetTeam and targetTeam == team) or (not attackPlayers and game.Players:GetPlayerFromCharacter(v)) then
teammate = true --es mi equipo
end
if (myTorso.Position - torso.Position).magnitude < dist and human.Health > 0 then
if (myTorso.Position - torso.Position).magnitude < closestdistance and human.Health > 0 then
for i,x in ipairs(allies) do
if x == v.Name or teammate then
table.insert(activeAllies,torso)
break
elseif i == #allies then
table.insert(potentialTargets,torso)
end
end
end
end
end
end
if #potentialTargets > 0 then
for i,v in ipairs(potentialTargets) do
if checkSight(v) then
table.insert(seeTargets,v)
end
end
if #seeTargets > 0 then
for i,v in ipairs(seeTargets) do
if (myTorso.Position - v.Position).magnitude < dist then
target = v.Head
dist = (myTorso.Position - v.Position).magnitude
end
end
else
for i,v in ipairs(potentialTargets) do
if (myTorso.Position - v.Position).magnitude < dist then
target = v.Head
dist = (myTorso.Position - v.Position).magnitude
end
end
end
end
currentTarget = target
end
function pathToLocation(target)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myTorso.Position, target.Position)
local waypoints = path:GetWaypoints()
for _,waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
Humanoid.Jump = true
end
Humanoid:MoveTo(waypoint.Position)
dofunction(function()
wait(0.5)
if Humanoid.WalkToPoint.Y > myTorso.Position.Y then
Humanoid.Jump = true
end
end)
local moveSuccess = Humanoid.MoveToFinished:Wait()
if not moveSuccess or not target.Parent or (checkDist(myTorso,target) < 30 and checkSight(target)) or currentTarget ~= target then
break
end
if checkDist(target,waypoints[#waypoints]) > 30 then
pathToLocation(target)
end
end
end
function walkRandom()
local randX = math.random(-100,100)
local randZ = math.random(-100,100)
local goal = myTorso.Position + Vector3.new(randX, 0, randZ)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myTorso.Position, goal)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for i,waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
Humanoid.Jump = true
end
Humanoid:MoveTo(waypoint.Position)
dofunction(function()
wait(0.5)
if Humanoid.WalkToPoint.Y > myTorso.Position.Y then
Humanoid.Jump = true
end
end)
local moveSuccess = Humanoid.MoveToFinished:Wait()
if not moveSuccess or currentTarget then
break
end
end
else
wait(2)
end
end
function drawM4()
if m4Equipped == false then
m4Equipped = true
equipSound:Play()
--Right Arm Setup
rShoulder.Part1 = nil
rArm.CFrame = aimer.CFrame * CFrame.new(1.25,0.05,-0.65) * CFrame.Angles(math.rad(80),math.rad(0),math.rad(-10))
rArmWeld.Part1 = rArm
--Left Arm Setup
lShoulder.Part1 = nil
lArm.CFrame = aimer.CFrame * CFrame.new(-0.35,0.05,-1.48) * CFrame.Angles(math.rad(84),math.rad(-3),math.rad(28))
lArmWeld.Part1 = lArm
--M4 Setup
m4Weld.Part0 = nil
m4.CFrame = aimer.CFrame * CFrame.new(0.65,0.37,-2.22) * CFrame.Angles(math.rad(-90),math.rad(0),math.rad(0))
m4Weld.Part0 = aimer
end
end
function yieldM4()
Humanoid.AutoRotate = true
gyro.MaxTorque = Vector3.new(0,0,0)
if weaponAimed == true then
weaponAimed = false
resetHead()
end
if m4Equipped == true then
m4Equipped = false
equipSound:Play()
--Right Arm setup
rArmWeld.Part1 = nil
rShoulder.Part1 = rArm
--Left Arm Setup
lArmWeld.Part1 = nil
lShoulder.Part1 = lArm
--M4 Setup
m4Weld.Part0 = nil
m4.CFrame = myTorso.CFrame * CFrame.new(0,0,0.6) * CFrame.Angles(math.rad(-90),math.rad(-60),math.rad(90))
m4Weld.Part0 = myTorso
end
end
function aim(target)
if weaponAimed == false then
game:GetService("TweenService"):Create(neck,TweenInfo.new(0.5),{C0 = neck.C0 * CFrame.Angles(0,math.rad(-15),0)}):Play()
end
Humanoid.AutoRotate = false
weaponAimed = true
gyro.CFrame = CFrame.new(myTorso.Position,target.Position)
gyro.MaxTorque = Vector3.new(0,math.huge,0)
if not reloading then
local aimCFrame = CFrame.new(aimer.Position,target.Position)
aimCFrame = aimCFrame - aimCFrame.Position
local negateCFrame = myTorso.CFrame - myTorso.Position
local newC0 = CFrame.new(0,0.5,0) * negateCFrame:Inverse() * aimCFrame
local x,y,z = newC0:ToEulerAnglesXYZ()
x = math.clamp(x,-0.8,0.8) --So his aiming isn't crazy backwards
newC0 = CFrame.new(0,0.5,0) * CFrame.fromEulerAnglesXYZ(x,0,0)
local lookDiff = (newC0.LookVector - aimerWeld.C0.LookVector).Magnitude
game:GetService("TweenService"):Create(aimerWeld,TweenInfo.new(lookDiff * 0),{C0 = newC0}):Play()
local newC0 = CFrame.new(0,1,0) * CFrame.Angles(-1.5 + math.rad(aimer.Orientation.X),math.rad(15),math.rad(180)) ---1.5 -
game:GetService("TweenService"):Create(neck,TweenInfo.new(lookDiff * 0),{C0 = newC0}):Play()
npc.HumanoidRootPart.CFrame = CFrame.new(npc.HumanoidRootPart.Position,Vector3.new(target.Position.x,npc.HumanoidRootPart.Position.y,npc.Position.z))
wait(lookDiff*0)
end
end
function resetHead()
game:GetService("TweenService"):Create(neck,TweenInfo.new(0.5),{C0 = CFrame.new(0,1,0) * CFrame.Angles(math.rad(-90),0,math.rad(180))}):Play()
end
function shoot(target)
if weaponCool == true and reloading == false then
weaponCool = false
local shot
if checkDist(target,myTorso) > 60 then
shot = 1
else
shot = 10
end
for i = 1, shot do
wait(0.1)
mag = mag - 1
flash:Emit(1)
local flash2 = Instance.new("PointLight")
game:GetService("Debris"):AddItem(flash2,0.03)
local bullet = Instance.new("Part")
bullet.Name = "bullet"
bullet.Size = Vector3.new(0.5,0.1,0.3) --evade
bullet.BrickColor = BrickColor.new("Gold")
bullet.Material = Enum.Material.Neon
bullet.CFrame = barrel.CFrame
--bullet.CFrame = CFrame.new(barrel.CFrame.Position) * CFrame.Angles(barrel.CFrame:toEulerAnglesXYZ().x, barrel.CFrame:toEulerAnglesXYZ().y, 0)
local barrelCFrame = barrel.CFrame
local newCFrame = CFrame.Angles(math.rad(0),0,math.rad(0))
-- Asigna el nuevo CFrame al objeto bullet
bullet.CFrame = bullet.CFrame:ToWorldSpace(newCFrame)
bullet.CanCollide = false
bullet.Touched:Connect(function(obj)
if not obj:IsDescendantOf(npc) then
local human = obj.Parent:FindFirstChild("Humanoid")
if human then
if obj.Name == "Head" then
human:TakeDamage(80)
else
human:TakeDamage(math.random(20,30))
end
if human.Health <= 0 then
if human.RootPart == currentTarget then
--Update target as soon as we kill the current one
findTarget()
end
end
end
bullet:Destroy()
end
end)
bullet.Parent = workspace
fireSound:Play()
local spread = Vector3.new(math.random(-shot,shot)/100,math.random(-shot,shot)/100)
--local spread = Vector3.new(math.random(-shot,shot)/300,math.random(-shot,shot)/100*1.5,math.random(-shot,shot)/300)
--local spread = Vector3.new(0,math.random(-shot,shot)/100*2.5,0)
local bv = Instance.new("BodyVelocity",bullet)
bv.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
bv.Velocity = (aimer.CFrame.LookVector + spread) * 300
local s = Instance.new("Sound",bullet)
s.Volume = 0.7
s.PlaybackSpeed = 7
s.Looped = true
s.SoundId = "rbxasset://sounds/Rocket whoosh 01.wav"
s:Play()
local a1 = Instance.new("Attachment",bullet)
a1.Position = Vector3.new(0,0.05,0)
local a2 = Instance.new("Attachment",bullet)
a2.Position = Vector3.new(0,-0.05,0)
local t = Instance.new("Trail",bullet)
t.Attachment0 = a1
t.Attachment1 = a2
t.Color = ColorSequence.new(bullet.Color)
t.WidthScale = NumberSequence.new(0.1,0.01)
t.Lifetime = 0.3
--TODO ADD KICK
game:GetService("Debris"):AddItem(bullet, 5)
end
if mag <= 0 then
reload()
end
dofunction(function()
wait(1)
weaponCool = true
end)
end
end
function reload()
if weaponAimed == true then
resetHead()
weaponAimed = false
end
reloadSound:Play()
reloading = true
yieldM4()
m4Weld.Part0 = nil
m4.CFrame = lArm.CFrame * CFrame.new(0.6,-1.3,0.2) * CFrame.Angles(math.rad(180),0,0)
m4Weld.Part0 = lArm
reloadAnimation:Play()
reloadAnimation:AdjustSpeed(3)
reloadAnimation.Stopped:Wait()
reloading = false
mag = fullMag
drawM4()
end
function yieldWeapons()
yieldM4()
if weaponAimed == true then
weaponAimed = false
resetHead()
end
end
function checkCluster(target)
--Check for nearby allies
for i,v in ipairs(activeAllies) do
if checkDist(target,v) < 30 then
return false
end
end
--Check if enemies are paired close together
for i,v in ipairs(potentialTargets) do
if v ~= target then
if checkDist(target,v) < 15 then
return true
end
end
end
return false
end
function movementLoop()
while Humanoid.Health>0 do
if currentTarget then
if checkDist(currentTarget,myTorso) > 30 or not checkSight(currentTarget) then
pathToLocation(currentTarget)
elseif checkDist(currentTarget,myTorso) > 8 then
if math.random(0,1) == 1 then
Humanoid:Move(myTorso.CFrame.RightVector)
else
Humanoid:Move(-myTorso.CFrame.RightVector)
end
wait(.5) --.5)
end
else
local randomAction = math.random(4)
if randomAction == 3 then
walkRandom()
elseif randomAction == 2 then
--print("Look randomly")
end
wait(3)
end
wait(0.1)
end
end
function searchTargetLoop()
while Humanoid.Health>0 do
findTarget()
wait(3)
end
end
function aimingLoop()
while Humanoid.Health>0 do
if currentTarget then
if checkSight(currentTarget) then
aim(currentTarget)
gunPointedAt = currentTarget
else
task.wait()
end
else
task.wait()
end
task.wait()
end
end
function attackLoop()
while Humanoid.Health>0 do
if currentTarget then
status = "Hunting"
updateFace()
if checkSight(currentTarget) then
status = "Attacking"
updateFace()
local distance = checkDist(myTorso,currentTarget)
if distance > 15 then
if checkCluster(currentTarget) == true and distance < 100 and distance > 30 and grenadeCool then
else
drawM4()
repeat
wait()
until gunPointedAt == currentTarget
shoot(currentTarget)
end
else
for i,v in pairs(currentTarget.Parent:GetChildren()) do
if v:IsA("BasePart") and checkDist(v,myTorso) < 100 then
end
end
end
else
if weaponAimed == true then
weaponAimed = false
Humanoid.AutoRotate = true
gyro.MaxTorque = Vector3.new(0,0,0)
resetHead()
local newC0 = CFrame.new(0,0.5,0) * CFrame.Angles(-0.5,0,0)
local lookDiff = (newC0.LookVector - aimerWeld.C0.LookVector).Magnitude
game:GetService("TweenService"):Create(aimerWeld,TweenInfo.new(lookDiff * 0.2),{C0 = newC0}):Play()
end
end
else
status = "Idle"
updateFace()
yieldWeapons()
wait(2)
end
wait(0.1)
end
end
function Died()
yieldM4()
status = "Dead"
myFace.Texture = faces.Dead
for i,v in ipairs(npc:GetDescendants()) do
if v:IsA("BallSocketConstraint") then
v.Enabled = true
elseif v:IsA("BasePart") and v.Name ~= "HumanoidRootPart" and v ~= aimer then
v.CanCollide = false
elseif v:IsA("Motor6D") then
v:Destroy()
end
end
if npc.Settings.Respawn.Value then
wait(npc.Settings.RespawnDelay.Value)
clone.Parent = npc.Parent
end
for i,v in ipairs(npc:GetDescendants()) do
if v:IsA("BasePart") or v:IsA("Decal") then
game:GetService("TweenService"):Create(v,TweenInfo.new(0.2),{Transparency = 0}):Play()
end
end
wait(5)
--npc:Destroy()
end
Humanoid.Died:Connect(Died)
local oldHealth = Humanoid.Health
local soundSpeeds = {0.9,0.95,1,1.05,1.1}
Humanoid.HealthChanged:Connect(function(health)
if health < oldHealth and hurtSound.IsPlaying == false then
hurtSound.PlaybackSpeed = soundSpeeds[math.random(#soundSpeeds)]
hurtSound:Play()
dofunction(function()
myFace.Texture = faces.Hurt
wait(1)
if myFace.Texture == faces.Hurt then
myFace.Texture = faces[status]
end
end)
end
oldHealth = health
end)
dofunction(searchTargetLoop)
dofunction(attackLoop)
dofunction(movementLoop)
dofunction(aimingLoop)