How to make a trail follow a thrown prop

So i’m making a SWEP that throws a prop, but I want a trail to follow it once it’s thrown. How do I do that?

Here is my code:


SWEP.Author			= "Lord_Melvin" -- These two options will be shown when you have the weapon highlighted in the weapon selection menu
SWEP.Instructions		= "fires a regular punch"

SWEP.Spawnable = true
SWEP.AdminOnly = false

SWEP.Category				= "One Piece"
SWEP.Primary.ClipSize		= -1
SWEP.Primary.DefaultClip	= -1
SWEP.Primary.Automatic		= false
SWEP.Primary.Ammo		= "none"



SWEP.Secondary.ClipSize		= -1
SWEP.Secondary.DefaultClip	= -1
SWEP.Secondary.Automatic	= false
SWEP.Secondary.Ammo		= "none"
SWEP.Weight			= 5
SWEP.AutoSwitchTo		= false
SWEP.AutoSwitchFrom		= false

SWEP.Slot			= 1
SWEP.SlotPos			= 2
SWEP.DrawAmmo			= false
SWEP.DrawCrosshair		= true




SWEP.ViewModel			= "models/weapons/v_smg1.mdl"
SWEP.WorldModel			= "models/weapons/w_smg1.mdl"

local ShootSound = "weapons/one piece/fist/pistal.mp3"
local DeploySound = "weapons/one piece/fist/gomu gomu no.mp3"

function SWEP:Deploy()
		self:EmitSound( DeploySound )
end

function SWEP:PrimaryAttack()

	self.Weapon:SetNextPrimaryFire( CurTime() + 0.1 )


	self:ThrowChair( "models/props/luffy/fist/fist.mdl" )
	
	

end

--
-- Called when the rightmouse button is pressed
--
function SWEP:SecondaryAttack()

	-- Note we don't call SetNextSecondaryFire here because it's not
	-- automatic and so we let them fire as fast as they can click.

	-- Call 'ThrowChair' on self with this model
	self:ThrowChair( "models/props/luffy/fist/fist.mdl" )


end

--
-- A custom function we added. When you call this the player will fire a chair!
--
function SWEP:ThrowChair( model_file )

	--
	-- Play the shoot sound we precached earlier!
	--
	self:EmitSound( ShootSound )


	--
	-- If we're the client then this is as much as we want to do.
	-- We play the sound above on the client due to prediction.
	-- ( if we didn't they would feel a ping delay during multiplayer )
	--
	if ( CLIENT ) then return end

	--
	-- Create a prop_physics entity
	--
	local ent = ents.Create( "prop_physics" )

	--
	-- Always make sure that created entities are actually created!
	--
	if ( !IsValid( ent ) ) then return end

	--
	-- Set the entity's model to the passed in model
	--
	ent:SetModel( model_file )

	--
	-- Set the position to the player's eye position plus 16 units forward.
	-- Set the angles to the player'e eye angles. Then spawn it.
	--
	ent:SetPos( self.Owner:EyePos() + ( self.Owner:GetAimVector() * 16 ) )
	ent:SetAngles( self.Owner:EyeAngles() )
	ent:Spawn()


	--
	-- Now get the physics object. Whenever we get a physics object
	-- we need to test to make sure its valid before using it.
	-- If it isn't then we'll remove the entity.
	--
	local phys = ent:GetPhysicsObject()
	if ( !IsValid( phys ) ) then ent:Remove() return end


	--
	-- Now we apply the force - so the chair actually throws instead
	-- of just falling to the ground. You can play with this value here
	-- to adjust how fast we throw it.
	--
	local velocity = self.Owner:GetAimVector()
	velocity = velocity * 10000
	velocity = velocity + ( VectorRand() * 1000 ) -- a random element
	phys:ApplyForceCenter( velocity )
	
	
	timer.Simple(2.5, function()
	if ent:IsValid() then ent:Remove() end
	end)
	--
	-- Assuming we're playing in Sandbox mode we want to add this
	-- entity to the cleanup and undo lists. This is done like so.
	--
	cleanup.Add( self.Owner, "props", ent )

	undo.Create( "Thrown_punch" )
		undo.AddEntity( ent )
		undo.SetPlayer( self.Owner )
	undo.Finish()
end

Run this on the entity once you spawn it serverside: https://wiki.garrysmod.com/page/util/SpriteTrail

Make sure you store the return value to a variable, so if you undo the prop you can remove the trail as well.

I’m getting some errors, I also want to know if I need a string texture and were do I find my ent?


function SWEP:ThrowChair( model_file )

	--
	-- Play the shoot sound we precached earlier!
	--
	self:EmitSound( ShootSound )


	--
	-- If we're the client then this is as much as we want to do.
	-- We play the sound above on the client due to prediction.
	-- ( if we didn't they would feel a ping delay during multiplayer )
	
	
	
	--
	if ( CLIENT ) then return end

	--
	-- Create a prop_physics entity
	--
	local ent = ents.Create( "prop_physics" )

	--
	-- Always make sure that created entities are actually created!
	--
	if ( !IsValid( ent ) ) then return end

	--
	-- Set the entity's model to the passed in model
	--
	
	util.SpriteTrail( ent,0,Color(255,163,128,255) ,true, 100, 100, 2.5, 0.0025)

	
	ent:SetModel( model_file )

	--
	-- Set the position to the player's eye position plus 16 units forward.
	-- Set the angles to the player'e eye angles. Then spawn it.
	--
	ent:SetPos( self.Owner:EyePos() + ( self.Owner:GetAimVector() * 16 ) )
	ent:SetAngles( self.Owner:EyeAngles() )
	ent:Spawn()


	--
	-- Now get the physics object. Whenever we get a physics object
	-- we need to test to make sure its valid before using it.
	-- If it isn't then we'll remove the entity.
	--
	local phys = ent:GetPhysicsObject()
	if ( !IsValid( phys ) ) then ent:Remove() return end


	--
	-- Now we apply the force - so the chair actually throws instead
	-- of just falling to the ground. You can play with this value here
	-- to adjust how fast we throw it.
	--
	local velocity = self.Owner:GetAimVector()
	velocity = velocity * 10000
	velocity = velocity + ( VectorRand() * 1000 ) -- a random element
	phys:ApplyForceCenter( velocity )
	
	
	timer.Simple(2.5, function()
	if ent:IsValid() then ent:Remove() end
	end)
	--
	-- Assuming we're playing in Sandbox mode we want to add this
	-- entity to the cleanup and undo lists. This is done like so.
	--
	cleanup.Add( self.Owner, "props", ent )

	undo.Create( "Thrown_punch" )
		undo.AddEntity( ent )
		undo.SetPlayer( self.Owner )
	undo.Finish()
end

[editline]12th May 2016[/editline]

Error:

[ERROR] addons/one piece swep/lua/weapons/weapon_punch/shared.lua:101: bad argument #9 to ‘SpriteTrail’ (string expected, got no value)

  1. SpriteTrail - [C]:-1
  2. ThrowChair - addons/one piece swep/lua/weapons/weapon_punch/shared.lua:101
    3. unknown - addons/one piece swep/lua/weapons/weapon_punch/shared.lua:46

Ok I switched the ent and I got this error

[ERROR] addons/one piece swep/lua/weapons/weapon_punch/shared.lua:101: Tried to use a NULL entity!

  1. SpriteTrail - [C]:-1
  2. ThrowChair - addons/one piece swep/lua/weapons/weapon_punch/shared.lua:101
    3. unknown - addons/one piece swep/lua/weapons/weapon_punch/shared.lua:46

Code:


function SWEP:ThrowChair( model_file )

	--
	-- Play the shoot sound we precached earlier!
	--
	self:EmitSound( ShootSound )


	--
	-- If we're the client then this is as much as we want to do.
	-- We play the sound above on the client due to prediction.
	-- ( if we didn't they would feel a ping delay during multiplayer )
	
	
	
	--
	if ( CLIENT ) then return end

	--
	-- Create a prop_physics entity
	--
	local ent = ents.Create( "prop_physics" )

	--
	-- Always make sure that created entities are actually created!
	--
	if ( !IsValid( ent ) ) then return end

	--
	-- Set the entity's model to the passed in model
	--
	
	util.SpriteTrail( ThrowChair,0,Color(255,163,128,255) ,true, 100, 100, 2.5, 0.0025)

	
	ent:SetModel( model_file )

	--
	-- Set the position to the player's eye position plus 16 units forward.
	-- Set the angles to the player'e eye angles. Then spawn it.
	--
	ent:SetPos( self.Owner:EyePos() + ( self.Owner:GetAimVector() * 16 ) )
	ent:SetAngles( self.Owner:EyeAngles() )
	ent:Spawn()


	--
	-- Now get the physics object. Whenever we get a physics object
	-- we need to test to make sure its valid before using it.
	-- If it isn't then we'll remove the entity.
	--
	local phys = ent:GetPhysicsObject()
	if ( !IsValid( phys ) ) then ent:Remove() return end


	--
	-- Now we apply the force - so the chair actually throws instead
	-- of just falling to the ground. You can play with this value here
	-- to adjust how fast we throw it.
	--
	local velocity = self.Owner:GetAimVector()
	velocity = velocity * 100000
	velocity = velocity + ( VectorRand() * 1000 ) -- a random element
	phys:ApplyForceCenter( velocity )
	
	
	timer.Simple(2.5, function()
	if ent:IsValid() then ent:Remove() end
	end)
	--
	-- Assuming we're playing in Sandbox mode we want to add this
	-- entity to the cleanup and undo lists. This is done like so.
	--
	cleanup.Add( self.Owner, "props", ent )

	undo.Create( "Thrown_punch" )
		undo.AddEntity( ent )
		undo.SetPlayer( self.Owner )
	undo.Finish()
end

Well, obviously it’s a null entity, nowhere in the code do I see another instance of “ThrowChair” as an entity…

If you take a close look at the wiki, it says its first argument is an entity and ThrowChair isn’t an entity, it’s a method of “SWEP”. Replace “ThrowChair” with “ent” which is the entity the SWEP creates. Finally, as previously mentioned:

Make a reference to the return value of util.SpriteTrail, which is another entity, so that you may remove it when the thrown entity is removed, or manipulate it after it’s created.

Sorry for being so needy but how would I store the return value to a variable? Like this?


local trail = util.SpriteTrail( ent,0,Color(255,163,128,255) ,true, 100, 100, 2.5, 0.0025)

Once again, sorry for being so hopeless. I’m new to lua and I should probably already know how to do this. :frown:

Like that, except make it a variable of the thrown entity itself, that way you can access it outside of that scope, as in your example, it’s a local variable.

ent.trail = …

You should probably keep track of the thrown entities as well by adding them onto a table of SWEP then removing them as they get removed.

I got this error:

[ERROR] addons/one piece swep/lua/weapons/weapon_punch/shared.lua:101: bad argument #9 to ‘SpriteTrail’ (string expected, got no value)

  1. SpriteTrail - [C]:-1
  2. ThrowChair - addons/one piece swep/lua/weapons/weapon_punch/shared.lua:101
    3. unknown - addons/one piece swep/lua/weapons/weapon_punch/shared.lua:46

Here is my code:


function SWEP:ThrowChair( model_file )

	--
	-- Play the shoot sound we precached earlier!
	--
	self:EmitSound( ShootSound )


	--
	-- If we're the client then this is as much as we want to do.
	-- We play the sound above on the client due to prediction.
	-- ( if we didn't they would feel a ping delay during multiplayer )
	
	
	
	--
	if ( CLIENT ) then return end

	--
	-- Create a prop_physics entity
	--
	local ent = ents.Create( "prop_physics" )

	--
	-- Always make sure that created entities are actually created!
	--
	if ( !IsValid( ent ) ) then return end

	--
	-- Set the entity's model to the passed in model
	--
	
	ent.trail = util.SpriteTrail( ent,0,Color(255,163,128,255) ,true, 100, 100, 2.5, 0.0025)

	
	ent:SetModel( model_file )

	--
	-- Set the position to the player's eye position plus 16 units forward.
	-- Set the angles to the player'e eye angles. Then spawn it.
	--
	ent:SetPos( self.Owner:EyePos() + ( self.Owner:GetAimVector() * 16 ) )
	ent:SetAngles( self.Owner:EyeAngles() )
	ent:Spawn()


	--
	-- Now get the physics object. Whenever we get a physics object
	-- we need to test to make sure its valid before using it.
	-- If it isn't then we'll remove the entity.
	--
	local phys = ent:GetPhysicsObject()
	if ( !IsValid( phys ) ) then ent:Remove() return end


	--
	-- Now we apply the force - so the chair actually throws instead
	-- of just falling to the ground. You can play with this value here
	-- to adjust how fast we throw it.
	--
	local velocity = self.Owner:GetAimVector()
	velocity = velocity * 100000
	velocity = velocity + ( VectorRand() * 1000 ) -- a random element
	phys:ApplyForceCenter( velocity )
	
	
	timer.Simple(2.5, function()
	if ent:IsValid() then ent:Remove() end
	end)
	--
	-- Assuming we're playing in Sandbox mode we want to add this
	-- entity to the cleanup and undo lists. This is done like so.
	--
	cleanup.Add( self.Owner, "props", ent )

	undo.Create( "Thrown_punch" )
		undo.AddEntity( ent )
		undo.SetPlayer( self.Owner )
	undo.Finish()
end

[editline]14th May 2016[/editline]

Nvm I got it working!