• Delay in bullet impact.
    8 replies, posted
Is there a way to make it where a "shot" is fired only at a certain point in a weapon's animation? I'm trying to make some melee SWEPs, but it's odd how the weapon hits a surface before the animation is at the right frame where it looks like it's hitting something.
You could use a timer.Simple where the ShootBullets function is called with some math to determine a reasonable delay for impact depending on the distance of the trace.
[QUOTE=KingofBeast;42353623]You could use a timer.Simple where the ShootBullets function is called with some math to determine a reasonable delay for impact depending on the distance of the trace.[/QUOTE] Sorry, I'm not all that familiar with how to implement this in my lua. Here's a snippet of the PrimaryAttack function: [code]function SWEP:PrimaryAttack() local tr = {} tr.start = self.Owner:GetShootPos() tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 ) tr.filter = self.Owner tr.mask = MASK_SHOT local trace = util.TraceLine( tr ) self:DoIdle(1) self.Weapon:SetNextSecondaryFire(CurTime() + 0.5) self.Weapon:SetNextPrimaryFire(CurTime() + 0.5) self.Owner:SetAnimation( PLAYER_ATTACK1 ) if ( trace.Hit ) then if (trace.Hit) and (trace.Entity:IsWorld()) then util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal) self:EmitSound("Weapon_Knife.HitWall") local effectdata = EffectData() effectdata:SetOrigin(trace.HitPos) effectdata:SetEntity(self.Owner:GetViewModel()) effectdata:SetStart(trace.HitPos) effectdata:SetNormal(trace.HitNormal) effectdata:SetScale( 1.5 ) effectdata:SetRadius( 0.9 ) effectdata:SetMagnitude( 0.6 ) util.Effect( "Sparks", effectdata ) end if trace.Entity:IsPlayer() or string.find(trace.Entity:GetClass(),"npc") or string.find(trace.Entity:GetClass(),"prop_ragdoll") then self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER) bullet = {} bullet.Num = 1 bullet.Src = self.Owner:GetShootPos() bullet.Dir = self.Owner:GetAimVector() bullet.Spread = Vector(0, 0, 0) bullet.Tracer = 0 bullet.Force = 10 bullet.Damage = 35 self.Owner:FireBullets(bullet) self.Weapon:EmitSound( "weapons/knife/knife_hit" .. math.random(1, 4) .. ".wav" ) else self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER) bullet = {} bullet.Num = 1 bullet.Src = self.Owner:GetShootPos() bullet.Dir = self.Owner:GetAimVector() bullet.Spread = Vector(0, 0, 0) bullet.Tracer = 0 bullet.Force = 10 bullet.Damage = 35 self.Owner:FireBullets(bullet) self.Weapon:EmitSound(self.WallSound,100,math.random(90,120)) util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal) end else self.Weapon:EmitSound(self.MissSound,100,math.random(90,120)) self.Weapon:SendWeaponAnim(ACT_VM_MISSCENTER) self.Weapon:SetNextSecondaryFire(CurTime() + 0.8) end end[/code]
Try this: [CODE]function SWEP:PrimaryAttack() timer.Simple(0.5,function() local tr = {} tr.start = self.Owner:GetShootPos() tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 ) tr.filter = self.Owner tr.mask = MASK_SHOT local trace = util.TraceLine( tr ) end) self:DoIdle(1) self.Weapon:SetNextSecondaryFire(CurTime() + 0.5) self.Weapon:SetNextPrimaryFire(CurTime() + 0.5) self.Owner:SetAnimation( PLAYER_ATTACK1 ) if ( trace.Hit ) then if (trace.Hit) and (trace.Entity:IsWorld()) then util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal) self:EmitSound("Weapon_Knife.HitWall") local effectdata = EffectData() effectdata:SetOrigin(trace.HitPos) effectdata:SetEntity(self.Owner:GetViewModel()) effectdata:SetStart(trace.HitPos) effectdata:SetNormal(trace.HitNormal) effectdata:SetScale( 1.5 ) effectdata:SetRadius( 0.9 ) effectdata:SetMagnitude( 0.6 ) util.Effect( "Sparks", effectdata ) end if trace.Entity:IsPlayer() or string.find(trace.Entity:GetClass(),"npc") or string.find(trace.Entity:GetClass(),"prop_ragdoll") then self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER) bullet = {} bullet.Num = 1 bullet.Src = self.Owner:GetShootPos() bullet.Dir = self.Owner:GetAimVector() bullet.Spread = Vector(0, 0, 0) bullet.Tracer = 0 bullet.Force = 10 bullet.Damage = 35 self.Owner:FireBullets(bullet) self.Weapon:EmitSound( "weapons/knife/knife_hit" .. math.random(1, 4) .. ".wav" ) else self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER) bullet = {} bullet.Num = 1 bullet.Src = self.Owner:GetShootPos() bullet.Dir = self.Owner:GetAimVector() bullet.Spread = Vector(0, 0, 0) bullet.Tracer = 0 bullet.Force = 10 bullet.Damage = 35 self.Owner:FireBullets(bullet) self.Weapon:EmitSound(self.WallSound,100,math.random(90,120)) util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal) end else self.Weapon:EmitSound(self.MissSound,100,math.random(90,120)) self.Weapon:SendWeaponAnim(ACT_VM_MISSCENTER) self.Weapon:SetNextSecondaryFire(CurTime() + 0.8) end end[/CODE]
Fortune, Now it's saying "attempt to index global 'trace' (a nil value)." The line it points out is the "if ( trace.Hit ) then" statement.
[QUOTE=Fidchell;42354108]Fortune, Now it's saying "attempt to index global 'trace' (a nil value)." The line it points out is the "if ( trace.Hit ) then" statement.[/QUOTE] Woops hang on, replace this: [CODE] timer.Simple(0.5,function() local tr = {} tr.start = self.Owner:GetShootPos() tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 ) tr.filter = self.Owner tr.mask = MASK_SHOT local trace = util.TraceLine( tr ) end)[/CODE] With this: [CODE]timer.Simple(0.5,function() local tr = {} tr.start = self.Owner:GetShootPos() tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 ) tr.filter = self.Owner tr.mask = MASK_SHOT trace = util.TraceLine( tr ) end)[/CODE] I forgot that it would become local to the timer, that should fix it.
That won't help. Give me a moment, I'll fix it up. [b]Edited:[/b] Give this a whirl. [lua] local hitdelay = 0.5-- Edit this variable to your liking function SWEP:PrimaryAttack() local tr = {} tr.start = self.Owner:GetShootPos() tr.endpos = self.Owner:GetShootPos() + ( self.Owner:GetAimVector() * 85 ) tr.filter = self.Owner tr.mask = MASK_SHOT local trace = util.TraceLine( tr ) self:DoIdle(1) self.Weapon:SetNextSecondaryFire(CurTime() + 0.5) self.Weapon:SetNextPrimaryFire(CurTime() + 0.5) self.Owner:SetAnimation( PLAYER_ATTACK1 ) self.Weapon:EmitSound(self.MissSound,100,math.random(90,120)) -- Woosh sound no matter what if ( trace.Hit ) then if (trace.Entity:IsWorld()) then util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal) self:EmitSound("Weapon_Knife.HitWall") local effectdata = EffectData() effectdata:SetOrigin(trace.HitPos) effectdata:SetEntity(self.Owner:GetViewModel()) effectdata:SetStart(trace.HitPos) effectdata:SetNormal(trace.HitNormal) effectdata:SetScale( 1.5 ) effectdata:SetRadius( 0.9 ) effectdata:SetMagnitude( 0.6 ) timer.Simple(hitdelay, function() util.Effect( "Sparks", effectdata ) end) elseif trace.Entity:IsPlayer() or string.find(trace.Entity:GetClass(),"npc") or string.find(trace.Entity:GetClass(),"prop_ragdoll") then self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER) bullet = {} bullet.Num = 1 bullet.Src = self.Owner:GetShootPos() bullet.Dir = self.Owner:GetAimVector() bullet.Spread = Vector(0, 0, 0) bullet.Tracer = 0 bullet.Force = 10 bullet.Damage = 35 local wep = self.Weapon local own = self.Owner timer.Simple(hitdelay, function() if (!wep or !own or !own:IsValid() or !wep:IsValid()) then return end own:FireBullets(bullet) wep:EmitSound( "weapons/knife/knife_hit" .. math.random(1, 4) .. ".wav" ) end) else self.Weapon:SendWeaponAnim(ACT_VM_HITCENTER) bullet = {} bullet.Num = 1 bullet.Src = self.Owner:GetShootPos() bullet.Dir = self.Owner:GetAimVector() bullet.Spread = Vector(0, 0, 0) bullet.Tracer = 0 bullet.Force = 10 bullet.Damage = 35 local wep = self.Weapon local own = self.Owner timer.Simple(hitdelay, function() if (!wep or !own or !own:IsValid() or !wep:IsValid()) then return end own:FireBullets(bullet) wep:EmitSound(self.WallSound,100,math.random(90,120)) util.Decal("ManhackCut", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal) end) end else self.Weapon:SendWeaponAnim(ACT_VM_MISSCENTER) self.Weapon:SetNextSecondaryFire(CurTime() + 0.8) end end[/lua]
KingofBeast, it works excellently! Thanks a bunch for your help. The only remaining problem now is that for some reason when I strike the world, the weapon doesn't go through an animation at all. EDIT: Also, I have noticed that in order to actually hit someone, you have to be in range, no matter how long the delay is. Is it possible to make it where the weapon only detects the distance between you and the enemy when the delay is over?
What about delay based on how far what you are shooting is? That would be cool.
Sorry, you need to Log In to post a reply to this thread.