Jump to content

Josh's Turret AI Script not working...


Recommended Posts

Good morning All,

 

Just wanted to ask if any of you kind folks happen to know if Josh ever managed to complete his Turret AI script as I had copied it and tried to use it but with errors unfortunately... :(

I keep getting the following error on his script -----> " Script Error - attempt to call method 'GetDistance' (a nil value) - Line 83

Does anyone know if Josh ever fixed and completed this script or no?! Or if one of you good gentlemen/ladies might have a turret AI script of your own or know where I might find one to use for a gun turret in my level would be very much appreciated indeed! :D


Here is the same code I found on Josh's blog here ------> Building Turret AI: Part 2

As a convenience I have posted Josh's code below also! Thanks and God bless all! :)



 

--Public
Script.target = nil--enemy to shoot
Script.range = 20
Script.health=100
Script.projectilepath = "Prefabs/Projectiles/tracer.pfb"

Script.shoot1sound=""--path "Fire 1 sound" "Wav file (*.wav):wav|Sound"
Script.shoot2sound=""--path "Fire 2 sound" "Wav file (*.wav):wav|Sound"
Script.shoot3sound=""--path "Fire 3 sound" "Wav file (*.wav):wav|Sound"

--Private
Script.lastfiretime=0
Script.mode = "idle"
Script.lastsearchtime=0
Script.searchfrequency = 500
Script.firefrequency = 50

function Script:Start()

   --Load sounds
   self.sound = {}

   self.sound.shoot = {}
   if self.shoot1sound~="" then self.sound.shoot[1] = Sound:Load(self.shoot1sound) end
   if self.shoot2sound~="" then self.sound.shoot[2] = Sound:Load(self.shoot2sound) end
   if self.shoot3sound~="" then self.sound.shoot[3] = Sound:Load(self.shoot3sound) end

   self.projectile = Prefab:Load(self.projectilepath)
   if self.projectile~=nil then
       self.projectile:Hide()
   end
   self.turret = self.entity:FindChild("turret")

   --Add muzzleflash to gun
   self.muzzle = self.entity:FindChild("muzzle")
   if self.muzzle~=nil then
       local mtl=Material:Create()
       mtl:SetBlendMode(5)
       self.muzzle:SetMaterial(mtl)
       mtl:Release()
       self.muzzleflash = Sprite:Create()
       self.muzzleflash:SetSize(0.35,0.35)
       local pos=self.muzzle:GetPosition(true)
       self.muzzleflash:SetPosition(pos,true)
       self.muzzleflash:SetParent(self.muzzle,true)
       mtl = Material:Load("Materials/Effects/muzzleflash.mat")
       if mtl then
           self.muzzleflash:SetMaterial(mtl)
           mtl:Release()
           mtl=nil
       end
       local light = PointLight:Create()
       light:SetRange(5)
       light:SetColor(1,0.75,0)
       light:SetParent(self.muzzleflash,flash)
       if light.world:GetLightQuality()<2 then
           light:SetShadowMode(0)    
       end
       self.muzzleflash:Hide()
   end

end

function Script:Release()
   if self.projectile~=nil then
       self.projectile:Release()
       self.projectile = nil
   end
end

function TurretSearchHook(entity,extra)


   if entity~=extra then
       if entity.script~=nil then
           if type(entity.script.health)=="number" then
               if entity.script.health>0 then
                   local d = extra:GetDistance(entity)
                   if d<extra.script.range then
                       if extra.script.target~=nil then
                           if extra.script:GetDistance(extra.script.target)>d then
                               if extra.script:GetTargetVisible(entity.script) then
                                   extra.script.target = entity.script
                               end
                           end
                       else
                           if extra.script:GetTargetVisible(entity.script) then
                               extra.script.target = entity.script
                           end
                       end
                   end
               end
           end
       end
   end
end

function Script:GetTargetVisible(target)
   if target==nil then
       target = self.target
   end
   if target==nil then
       return false
   end
   local pickinfo = PickInfo()
   local p0 = self.entity:GetAABB().center
   local p1 = target.entity:GetAABB().center
   local pickmode0 = self.entity:GetPickMode()
   local pickmode1 = target.entity:GetPickMode()
   self.entity:SetPickMode(0)
   target.entity:SetPickMode(0)
   local result = not self.entity.world:Pick(p0,p1,pickinfo,0,false,Collision.LineOfSight)
   self.entity:SetPickMode(pickmode0)
   target.entity:SetPickMode(pickmode1)    
   return result
end

function Script:UpdateWorld()

   if self.health>=0 then

       local currenttime = Time:GetCurrent()

       --Stop shooting if target is dead
       if self.target~=nil then
           if self.target.health<=0 then
               self.target = nil
           end
       end

       --Search for target
       if self.target==nil then
           if currenttime - self.lastsearchtime > self.searchfrequency then
               self.lastsearchtime = currenttime
               local pos = self.entity:GetPosition(true)
               local aabb = AABB(pos - Vec3(self.range), pos + Vec3(self.range))
               self.entity.world:ForEachEntityInAABBDo(aabb,"TurretSearchHook",self.entity)
           end
       end

       --Continuous visibility test
       if self.target~=nil then
           if currenttime - self.lastsearchtime > self.searchfrequency then
               self.lastsearchtime = currenttime
               if self:GetTargetVisible(self.target)==false then
                   self.target = nil
                   return
               end
           end
       end

       if self.target~=nil then

           --Motion tracking
           if self.turret~=nil then
               local p0 = self.turret:GetPosition(true)
               local p1 = self.target.entity:GetAABB().center
               local yplane = p1 - p0
               yplane.y=0
               self.turret:AlignToVector(yplane,1,0.1 / Time:GetSpeed(),0)
           end

           --Shoot
           if self.muzzle~=nil and self.projectile~=nil then
               if currenttime - self.lastfiretime > self.firefrequency then
                   self.lastfiretime = currenttime
                   local bullet = self.projectile:Instance()

                   self.muzzleflash:Show()
                   self.muzzleflash:EmitSound(self.sound.shoot[#self.sound.shoot])
                   self.muzzleflash:SetAngle(math.random(0,360))
                   self.muzzleflashtime=currenttime

                   if bullet~=nil then
                       bullet:Show()
                       bullet:SetPosition(self.muzzle:GetPosition(true),true)
                       bullet:SetRotation(self.muzzle:GetRotation(true),true)
                       if bullet.script~=nil then
                           bullet.script.owner = self
                           if type(bullet.script.Enable)=="function" then
                               bullet.script:Enable()
                           end
                           bullet:Turn(Math:Random(-3,3),Math:Random(-3,3),0)
                       end
                   end
               end
           end

       end

   end

   self:UpdateMuzzleFlash()

end

function Script:UpdateMuzzleFlash()
   if self.muzzleflashtime then
       if Time:GetCurrent()-self.muzzleflashtime<30 then
           self.muzzleflash:Show()
       else
           self.muzzleflash:Hide()
       end
   end
end

 

Link to comment
Share on other sites

Hello, and welcome. If you look at the soldier AI script, that basically acts like a moving turret. I think you might be better off using that as a starting point. You can make a copy of the script and then start modifying it to remove the movement code.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...