• Help with Particle Spiral Velocity
    1 replies, posted
I need some help with making a particle spiral around a frozen entity. I feel like I am going about this the wrong way, this is the relevant piece of code. It "somewhat" works but it isn't a clean spiral. Not very familiar with velocity in a 3d space. pos = initial entity pos (for all intents and purposes just assume (0,0,0)) [lua] timer.Create("ParticleVelocity", .01, 80, function() yaw = yaw + 8 if ( yaw > 360 ) then yaw = 0; end local yaw = yaw if ( yaw > 360 ) then yaw = yaw - 360; end x = radius * math.cos((yaw * math.pi) / 180) -- Just gets a point on a circle (radius 20) y = radius * math.sin((yaw * math.pi) / 180) local ppos = particle:GetPos() endPos = Vector(pos.x, pos.y, ppos.z) + Vector(x,y,4) --End pos is the original pos + the pos on the circle and a little bit higher. dx = endPos.x - ppos.x dy = endPos.y - ppos.y dz = endPos.z - ppos.z d = math.sqrt(dx*dx + dy*dy + dz*dz) vx = dx/d * 24 vy = dy/d * 24 vz = dz/d * 24 particle:SetVelocity( Vector(vx,vy,vz) ); end) [/lua]
[B]Note that I am assuming that you want the particle to orbit around the entity, correct me if I am wrong[/B] I would suggest using an effect for this and simply draw a sprite. Effects are located in the [I]lua/effects/[/I] directory, or [i]entities/effects/[/i] for gamemodes. In my example ([I]orbit.lua[/I]), I start by marking the effect for download and create a varible that points to the material the effect will use for the sprite: [code] AddCSLuaFile() EFFECT.matsprite = Material("effects/select_ring") [/code] The functions we are interested in for this effect is [URL="http://wiki.garrysmod.com/page/EFFECT/Init"]Init[/URL], [URL="http://wiki.garrysmod.com/page/EFFECT/Think"]Think[/URL] and [URL="http://wiki.garrysmod.com/page/EFFECT/Render"]Render[/URL]. Let us start with [URL="http://wiki.garrysmod.com/page/EFFECT/Init"]Init[/URL], it gets called when the effect is created. The first and only argument is an [URL="http://wiki.garrysmod.com/page/Category:CEffectData"]CEffectData[/URL] object, which contains data for the effect; example on that at the end. [code] function EFFECT:Init(data) local ent = data:GetEntity() -- get target entity if not IsValid(ent) then return -- if the entity is not valid, no need to continue end self:SetPos(ent:GetPos()) -- set the position of the effect at the entitys position -- NOTE: since your entity will be frozen we only set the position once here, if you plan -- to move the entity; set the position in the Think function -- get the render bounds of the entity local min, max = ent:GetRenderBounds() -- set the render bounds of the effect to be bigger than the entitys, because the sprite -- will most likely orbit outside the entitys render bounds; 50% larger will do(?) self:SetRenderBounds(min*1.5, max*1.5) self.entity = ent -- store the entity self.radius = data:GetRadius() -- store the radius end [/code] [URL="http://wiki.garrysmod.com/page/EFFECT/Think"]Think[/URL], this function is used for the logic of the effect; returning anything but true removes the effect. [code] function EFFECT:Think() local ent = self.entity -- use the entity specified in Init if not IsValid(ent) then return false -- if the entity is not valid, remove the effect end -- calculating the position of the sprite local radius = self.radius -- use the radius specified in Init local rad = RealTime() -- let us be lazy and just use the time as the radians :^) self.spritepos = ent:GetPos() + ent:GetRight()*math.cos(rad)*radius + ent:GetForward()*math.sin(rad)*radius return true --keep the effect alive end [/code] [URL="http://wiki.garrysmod.com/page/EFFECT/Render"]Render[/URL], the function that renders the effect; self-explanatory: [code] function EFFECT:Render() if self.spritepos then render.SetMaterial(self.matsprite) render.DrawSprite(self.spritepos, 16, 16, color_white) end end [/code] And that's it! Here is the full code: [code] AddCSLuaFile() EFFECT.matsprite = Material("effects/select_ring") function EFFECT:Init(data) local ent = data:GetEntity() -- get target entity if not IsValid(ent) then return -- if the entity is not valid, no need to continue end self:SetPos(ent:GetPos()) -- set the position of the effect at the entitys position -- NOTE: since your entity will be frozen we only set the position once here, if you plan -- to move the entity; set the position in the Think function -- get the render bounds of the entity local min, max = ent:GetRenderBounds() -- set the render bounds of the effect to be bigger than the entitys, because the sprite -- will most likely orbit outside the entitys render bounds; 50% larger will do(?) self:SetRenderBounds(min*1.5, max*1.5) self.entity = ent -- store the entity self.radius = data:GetRadius() -- store the radius end function EFFECT:Think() local ent = self.entity -- use the entity specified in Init if not IsValid(ent) then return false -- if the entity is not valid, remove the effect end -- calculating the position of the sprite local radius = self.radius -- use the radius specified in Init local rad = RealTime() -- let us be lazy and just use the time as the radians :^) self.spritepos = ent:GetPos() + ent:GetRight()*math.cos(rad)*radius + ent:GetForward()*math.sin(rad)*radius return true --keep the effect alive end function EFFECT:Render() if self.spritepos then render.SetMaterial(self.matsprite) render.DrawSprite(self.spritepos, 16, 16, color_white) end end [/code] To apply the effect, use [URL="http://wiki.garrysmod.com/page/util/Effect"]util.Effect[/URL] I suggest applying the effect CLIENTSIDE, because some clients might not have discovered the entity you are targeting, which will remove the effect for them. Applying the effect on an entity you are looking at: [code] lua_run_cl local data = EffectData() data:SetEntity(Entity(1):GetEyeTrace().Entity) data:SetRadius(24) util.Effect("orbit", data) [/code] Applying the effect when the entity is initialized: [code] function ENT:Initialize() if CLIENT then local data = EffectData() data:SetEntity(self) data:SetRadius(24) util.Effect("orbit", data) end end [/code] Good luck!
Sorry, you need to Log In to post a reply to this thread.