• Viewmodel Muzzleflash position
    32 replies, posted
hiya FP. Today i've been struggling with the repositioning of the muzzleflares on my custom SWEP. The whole swep visually is a SWEP creation kit weapon, with two guns on either side (Let's say its an akimbo weapon or something) What i'm trying to do is reposition the muzzleflash to fit the weapons on either side, using a switching function after every shot to switch between the two. I haven't been very successful, and the only results i can get is the muzzleflash originating on the weapon's muzzle, regardless of what i do. So, in basic, how can i change the position of the muzzle effect? here's code: [lua] if CLIENT then function SWEP:MuzzleEffect(elname, pos) local viewm = self.Owner:GetViewModel() local vm = self.VElements[""..elname..""].modelEnt local muzzleflash = EffectData() muzzleflash:SetOrigin(vm:GetPos() + vm:GetForward() * 60) -- testing purposes, usually just vm:GetPos + pos muzzleflash:SetStart(vm:GetPos() + vm:GetForward()* 60) -- same as above muzzleflash:SetEntity( viewm ) -- actual viewmodel muzzleflash:SetAttachment( viewm:LookupAttachment("muzzle") ) -- needed attachment to make this work muzzleflash:SetScale(1) -- a function that seems to be designed to scale the size of the effect, Doesn't do squat if i change it. print(muzzleflash:GetOrigin()) -- Returns more or less what i expect it to (Current Position of the viewmodel + offset of the muzzles of left/right gun) util.Effect("ChopperMuzzleFlash", muzzleflash, true, true) end end [/lua] This in general has returned the same thing over and over, a muzzleflash on the muzzle of the original ViewModel. I'm unable to edit its position. How can i do this? Thanks in advance!
bumps
bump. Anybody at all?
Could you create another viewmodel in your VElements array, invisible, positioned/parented where you want, and use that for the muzzleeffect only? Since you seem to have to use SetAttachment
[QUOTE=wh1t3rabbit;42106253]Could you create another viewmodel in your VElements array, invisible, positioned/parented where you want, and use that for the muzzleeffect only? Since you seem to have to use SetAttachment[/QUOTE] i tried this method first, it didn't succeed as well as i'd hope.
Instead of SetAttachment for the effect, you could get the attachment ( which returns .Pos, and .Ang ), and modify the attachment, then set the position and angle normally on the effect. Using that method, you could easily adjust the position and/or the angle.
So basically, the muzzleflash always appears on the first gun, right? Do you have any reliable way to get the muzzle position of the second gun? Also what happens if you don't set an entity and an attachment for the effect? From your comments, it looks like SetOrigin and SetStart change absolutely nothing, if that's true then it's probably the way the effect was coded and you won't be able to change that. There's a way around that using dummy entities but first you need a reliable way to get the muzzle position on both guns at any time.
[QUOTE=_Kilburn;42106687]Also what happens if you don't set an entity and an attachment for the effect? From your comments, it looks like SetOrigin and SetStart change absolutely nothing, if that's true then it's probably the way the effect was coded and you won't be able to change that.[/QUOTE] ChopperMuzzleFlash is defined in this file around line 538 [url]https://github.com/ValveSoftware/source-sdk-2013/blob/master/sp/src/game/client/hl2/fx_hl2_tracers.cpp[/url] It seems to only use the attachment and not the start parameter (but does use origin for something). A possible alternative is to recreate this effect in lua and make it use the given positions instead of the attachments. From the source it is just creating a particle emitter that sprays out particles of effects/combinemuzzle[0/1]., but then it calls CreateMuzzleflashELight (with the origin) which I'm not sure about, it creates some kind of entity light? [editline]7th September 2013[/editline] That 'entity light' is just a DynamicLight I believe, so it could definitley be all recreated in Lua.
[QUOTE=Acecool;42106589]Instead of SetAttachment for the effect, you could get the attachment ( which returns .Pos, and .Ang ), and modify the attachment, then set the position and angle normally on the effect. Using that method, you could easily adjust the position and/or the angle.[/QUOTE] Modify? As in, Attachment:SetPos() and then link it to the attachment? [editline]7th September 2013[/editline] [QUOTE=_Kilburn;42106687]So basically, the muzzleflash always appears on the first gun, right? Do you have any reliable way to get the muzzle position of the second gun? Also what happens if you don't set an entity and an attachment for the effect? From your comments, it looks like SetOrigin and SetStart change absolutely nothing, if that's true then it's probably the way the effect was coded and you won't be able to change that. There's a way around that using dummy entities but first you need a reliable way to get the muzzle position on both guns at any time.[/QUOTE] Yeah, appears on the viewmodel muzzle attachment of the first gun, always. [editline]7th September 2013[/editline] [QUOTE=_Kilburn;42106687] Also what happens if you don't set an entity and an attachment for the effect? From your comments, it looks like SetOrigin and SetStart change absolutely nothing, if that's true then it's probably the way the effect was coded and you won't be able to change that. [/QUOTE] It simply doesn't show up when i do that. No errors. [editline]7th September 2013[/editline] [QUOTE=wh1t3rabbit;42108188]ChopperMuzzleFlash is defined in this file around line 538 [url]https://github.com/ValveSoftware/source-sdk-2013/blob/master/sp/src/game/client/hl2/fx_hl2_tracers.cpp[/url] It seems to only use the attachment and not the start parameter (but does use origin for something). A possible alternative is to recreate this effect in lua and make it use the given positions instead of the attachments. From the source it is just creating a particle emitter that sprays out particles of effects/combinemuzzle[0/1]., but then it calls CreateMuzzleflashELight (with the origin) which I'm not sure about, it creates some kind of entity light? [editline]7th September 2013[/editline] That 'entity light' is just a DynamicLight I believe, so it could definitley be all recreated in Lua.[/QUOTE] Weird that it does that. I'll use a normal muzzleflash effect and try again. Just a particleemitter? i could probably do that. As long as i can get the effect to position properly i'm set to go.
If you PrintTable Attachment, you get Pos = Vector( ... ), Ang = Angle( ... ) You could simple change the position and angle, by referencing table.Pos or table.Ang; and instead of using SetAttachment for the effect, pass in position and angle ( ensure the effect is coded to accept either attachment OR pos/ang )
You can't change the default position, since you can't edit attachments positions without recompiling the model. But you can always offset your custom effects, etc.
[QUOTE=Robotboy655;42113531]You can't change the default position, since you can't edit attachments positions without recompiling the model. But you can always offset your custom effects, etc.[/QUOTE] How? i've tried doing it without the attachments. i still have to SetEntity to the viewmodel though
Seriously?? Read my post please! An attachment, when you PRINT it out, is a table that looks like this: [lua]local _table = { Pos = Vector( 111, 222, 333 ), Ang = Angle( 0, 90, 10 ) }[lua] Simply create a variable pointing to the attachment. We'll call that _table, as it's the same as the _table that I wrapped in Lua tags. [lua]_offsetPos = Vector( 0, 0, -5 ); _offsetAng = Angle( 0, 90, 0 ); _table.Pos = _table.Pos + _offsetPos; _table.Ang = _table.Ang + _offsetAng;[/lua] But, you have to make sure that your effect can take an input of Positions and Angles!!! Additionally, for your _offsetPos and _offsetAng be sure to RotateAroundAxis, and apply the proper mathematics otherwise if you stand still and rotate in place, it will not be attached with it properly... Handsome Matt keeps harassing me and marking my posts dumb, yet it provides your answer...
I wouldn't recommend using Ang+Angle or Pos+Vector, it could mess up position, use ang:RotateAroundAxis for angles and ang:Up()/ent:GetUp() functions for position.
[QUOTE=Robotboy655;42118244]I wouldn't recommend using Ang+Angle or Pos+Vector, it could mess up position, use ang:RotateAroundAxis for angles and ang:Up()/ent:GetUp() functions for position.[/QUOTE] That's what I said. Can you not read??? I'm being rated dumb by MATT WHO IS HARASSING ME, and you are not reading my post??? Robot I seriously expected you to know how to read? Seriously? See this in my post??? [B]Additionally, for your _offsetPos and _offsetAng be sure to RotateAroundAxis, and apply the proper mathematics otherwise if you stand still and rotate in place, it will not be attached with it properly...[/B] Robot, you're basically echoing me in each of your posts.
[QUOTE=Acecool;42120248]*Rage*[/QUOTE] I didn't read the thread at all, I answered OPs last post. You should've added that into the code since that's all I've read. I know how it sounds, but you first suggest one way and then correct yourself later, why not just post the proper way from the start? You should know that people are lazy and tend to just copy and paste the code.
[QUOTE=Acecool;42117042]Seriously?? Read my post please! An attachment, when you PRINT it out, is a table that looks like this: [lua]local _table = { Pos = Vector( 111, 222, 333 ), Ang = Angle( 0, 90, 10 ) }[lua] Simply create a variable pointing to the attachment. We'll call that _table, as it's the same as the _table that I wrapped in Lua tags. [lua]_offsetPos = Vector( 0, 0, -5 ); _offsetAng = Angle( 0, 90, 0 ); _table.Pos = _table.Pos + _offsetPos; _table.Ang = _table.Ang + _offsetAng;[/lua] But, you have to make sure that your effect can take an input of Positions and Angles!!! Additionally, for your _offsetPos and _offsetAng be sure to RotateAroundAxis, and apply the proper mathematics otherwise if you stand still and rotate in place, it will not be attached with it properly... Handsome Matt keeps harassing me and marking my posts dumb, yet it provides your answer...[/QUOTE] Sorry about that, was late at night and i could barely understand what you were saying. I'ts still morning and im not keeping up all the way, so could i ask one of you fine gentleman to elaborate on how to modify the pos? I've got the angles i believe, tell me if im on the right track: [lua] if CLIENT then function SWEP:MuzzleEffect(elname, pos) local viewm = self.Owner:GetViewModel() local vm = self.VElements[""..elname..""] local muzzleflash = EffectData() local _vmtbl = viewm:GetAttachment(viewm:LookupAttachment("muzzle")) local newpos = _vmtbl.Pos local newang = _vmtbl.Ang newang:RotateAroundAxis(newang:Up(), vm.angle.y) newang:RotateAroundAxis(newang:Right(), vm.angle.p) newang:RotateAroundAxis(newang:Forward(), vm.angle.r) newpos = vm.pos + _vmtbl.Pos muzzleflash:SetOrigin(newpos) muzzleflash:SetStart(newpos) muzzleflash:SetAngles(newang) muzzleflash:SetEntity( viewm ) --muzzleflash:SetAttachment( viewm:LookupAttachment("muzzle") ) muzzleflash:SetScale(1) util.Effect("AirboatMuzzleFlash", muzzleflash, true, true) end end [/lua] [editline]8th September 2013[/editline] Would it be more conventional for me to just use a particleemitter? im a bit wary of it, i hear that having alot of them is just a downright bad idea, and you should end particleemitters when they're done. Would i just remove it when the player holsters the weapon or dies? Thanks for the replys, i wouldnt know where to go past that.
Careful, Lua particle emitters emit particles in "absolute coordinates", which means that if you fire while running forward, the particles will not follow your gun and will instead stay behind, which will look wrong. There is a way to get the particles to follow an attachment point but it's rather tricky as you need to spawn the emitter at the map origin (0,0,0), use cam.Start3D to so it gets rendered at the desired position, and then manually render it. That's something you'd like to avoid if it's not necessary. Getting the position of the attachment and applying an offset to it isn't going to help you one bit. You can't come up with a solution if you don't know what the problem is. Clearly, the problem here comes from the fact that the effect you are using needs an attachment and an entity to compute its position, and there is no way to change that position otherwise. The easiest solution for that is to spawn a clientside entity using ClientsideModel (using any model, doesn't matter), parent it to your viewmodel, make it invisible, and then use it in muzzleflash:SetEntity. Attachment doesn't matter since if I remember correctly, no attachment will simply cause the effect to appear in the middle of the entity. This way you've got a way to control your effect and move it around. Once that's done, all you need to do is modify the position and angles of this invisible entity every time the viewmodel is drawn so it is always located at the muzzle. Of course, getting the position and angle of both muzzles might be problematic as well. It all depends on how you built your viewmodel. Since I'm not familiar with the SWEP creation kit, maybe you could post your entire code on Pastebin or something like that, so I can help you with that part.
[QUOTE=Robotboy655;42120696]Incoherent nonsense[/QUOTE] Where did I suggest one way, then change it? I've been telling him that he can access the position and angle all along from the Attachment table. He could go from there. Then, he still didn't read my post so I said it again, and again, and then I included that he should make sure he uses the RotateAroundAxis because he's obviously doesn't know how to properly access or modify those values; which is why I told him the proper way. You repeating me adds nothing to the thread?
[QUOTE=Acecool;42122762]Where did I suggest one way, then change it? I've been telling him that he can access the position and angle all along from the Attachment table. He could go from there. Then, he still didn't read my post so I said it again, and again, and then I included that he should make sure he uses the RotateAroundAxis because he's obviously doesn't know how to properly access or modify those values; which is why I told him the proper way. You repeating me adds nothing to the thread?[/QUOTE] I was talking about your post with the code only. Anyway, just shut up, this isn't going to help OP.
By the way, kinda unrelated here but since the above gentlemen can't stop arguing about it, there's a much easier way to apply an offset relatively to a given position and angle. You can use matrices instead. They're much cheaper than multiple calls to Forward, Right, Up and RotateAroundAxis, much more versatile, and they also make your code much more readable. This is how you use matrices: [lua]local att = viewm:GetAttachment(viewm:LookupAttachment("muzzle")) -- Create a default matrix local M = Matrix() -- Set the starting point M:Translate(att.Pos) M:Rotate(att.Ang) -- Apply position and angle offsets M:Translate(Vector(0, 0, 10)) M:Rotate(Angle(90, 0, 0)) -- Get the final position and angle local pos = M:GetTranslation() local ang = M:GetAngles()[/lua] Matrices are really versatile and are a bit more complex than what I'm going to tell you, but in this scenario you can consider a matrix as a "virtual player" with a position and a view angle. By default, a matrix starts with a position of (0, 0, 0) and a view angle of (0, 0, 0), this is called an identity matrix but you d. Translate moves that "player" in a direction relative to its current view angle (X is forward, Y is right, Z is up), and Rotate rotates its view angle (relatively to their current view angle as well). You can apply as many transformations as you want, although you need to be wary of the order in which you apply them. Walking 10 meters forward then turning 45 degrees to the left isn't the same as turning 45 degrees to the left then walking 10 meters forward. When you're done, all you need to do is use GetTranslation and GetAngle to retrieve the position and angles of that "virtual player". In the end it's mostly the same thing as using angle functions such as RotateAroundAxis, except it's much cheaper and it also makes your code much more readable, at least in my opinion. That was just for general knowledge. I doubt you'll need that here. :v:
[QUOTE=_Kilburn;42122426]Careful, Lua particle emitters emit particles in "absolute coordinates", which means that if you fire while running forward, the particles will not follow your gun and will instead stay behind, which will look wrong. There is a way to get the particles to follow an attachment point but it's rather tricky as you need to spawn the emitter at the map origin (0,0,0), use cam.Start3D to so it gets rendered at the desired position, and then manually render it. That's something you'd like to avoid if it's not necessary. Getting the position of the attachment and applying an offset to it isn't going to help you one bit. You can't come up with a solution if you don't know what the problem is. Clearly, the problem here comes from the fact that the effect you are using needs an attachment and an entity to compute its position, and there is no way to change that position otherwise. The easiest solution for that is to spawn a clientside entity using ClientsideModel (using any model, doesn't matter), parent it to your viewmodel, make it invisible, and then use it in muzzleflash:SetEntity. Attachment doesn't matter since if I remember correctly, no attachment will simply cause the effect to appear in the middle of the entity. This way you've got a way to control your effect and move it around. Once that's done, all you need to do is modify the position and angles of this invisible entity every time the viewmodel is drawn so it is always located at the muzzle. Of course, getting the position and angle of both muzzles might be problematic as well. It all depends on how you built your viewmodel. Since I'm not familiar with the SWEP creation kit, maybe you could post your entire code on Pastebin or something like that, so I can help you with that part.[/QUOTE] all of the visual items on the weapon are ClientSideModels. [lua] if CLIENT then function SWEP:MuzzleEffect(elname, pos) local viewm = self.Owner:GetViewModel() local vm = self.VElements[""..elname..""] local muzzleflash = EffectData() muzzleflash:SetOrigin(vm.modelEnt:GetPos()) muzzleflash:SetStart(vm.modelEnt:GetPos()) muzzleflash:SetEntity( vm.modelEnt ) muzzleflash:SetScale(1) util.Effect("AirboatMuzzleFlash", muzzleflash, true, true) end end [/lua] like that? [editline]9th September 2013[/editline] Screw it, here's the whole weapon on pastebin. [url]http://pastebin.com/Fgmwpj8u[/url]
Here is small snippet from one of my sweps where I create muzzleflash (a bit messy tho): [code] if CLIENT and self:IsShooting() and self:Clip1() > 0 and IsValid(self.VElements["rotate_main"].modelEnt) then local effectdata = EffectData() effectdata:SetOrigin( self.VElements["rotate_main"].modelEnt:GetPos()+self.VElements["rotate_main"].modelEnt:GetAngles():Up()*4 ) effectdata:SetAngles( self.Owner:GetAimVector():Angle() ) effectdata:SetScale( 2 ) util.Effect( "MuzzleEffect", effectdata ) end [/code] Here is how it looks like: [t]http://bbq.to/2013-09-09_00003_731d.jpg[/t] Maybe this can help.
[QUOTE=Archemyde;42125301] [lua] if CLIENT then function SWEP:MuzzleEffect(elname, pos) local viewm = self.Owner:GetViewModel() local vm = self.VElements[""..elname..""] local muzzleflash = EffectData() muzzleflash:SetOrigin(vm.modelEnt:GetPos()) muzzleflash:SetStart(vm.modelEnt:GetPos()) muzzleflash:SetEntity( vm.modelEnt ) muzzleflash:SetScale(1) util.Effect("AirboatMuzzleFlash", muzzleflash, true, true) end end [/lua] like that?[/QUOTE] Well according to the way the SWEP creation kit seems to work, that's pretty damn close. I think the easiest solution would be adding an invisible element directly using the creation kit, which is placed at the muzzle of each gun. Then all you'd need to do would be to retrieve this invisible element from self.VElements, and use it as the entity for your muzzleflash. [lua] if CLIENT then function SWEP:MuzzleEffect(elname, pos) local vm = self.VElements[elname] local muzzleflash = EffectData() muzzleflash:SetEntity( vm.modelEnt ) util.Effect("AirboatMuzzleFlash", muzzleflash, true, true) end end [/lua] Much shorter version of what you wrote. What was the point of writing self.VElements[""..elname..""] by the way? That looks completely pointless. Unless elname might not be a string and you want to force it to become a string, in which case it'd be just better to use tostring().
[QUOTE=_Kilburn;42128635]Well according to the way the SWEP creation kit seems to work, that's pretty damn close. I think the easiest solution would be adding an invisible element directly using the creation kit, which is placed at the muzzle of each gun. Then all you'd need to do would be to retrieve this invisible element from self.VElements, and use it as the entity for your muzzleflash. [lua] if CLIENT then function SWEP:MuzzleEffect(elname, pos) local vm = self.VElements[elname] local muzzleflash = EffectData() muzzleflash:SetEntity( vm.modelEnt ) util.Effect("AirboatMuzzleFlash", muzzleflash, true, true) end end [/lua] Much shorter version of what you wrote. What was the point of writing self.VElements[""..elname..""] by the way? That looks completely pointless. Unless elname might not be a string and you want to force it to become a string, in which case it'd be just better to use tostring().[/QUOTE] The PrimaryAttack function switches inbetween each gun, flipping back and forth inbetween the two elements that act as the muzzle. I run SWEP:MuzzleEffect(element_name,pos) according to which side the gun is on. Just seemed the most natural at the time, i tend to be an incredibly messy coder. [editline]9th September 2013[/editline] Thank you so much grobov, your example helped me learn about those modelEnts a bit more. The muzzleflashes now appear where i expect, but now there's one more issue, The muzzle flashes do not move with the VM. they appear in the world where they initiate and stay there. [editline]9th September 2013[/editline] also, MuzzleEffect seems to be the only flash effect that will work with this as intended. If i want different ones i guess i'll need to learn how to make them myself.
[QUOTE=Archemyde;42129176]but now there's one more issue, The muzzle flashes do not move with the VM. they appear in the world where they initiate and stay there.[/QUOTE] That's the problem I was talking about earlier. You need to attach the muzzle effect to something so you can have control over its position. Did you try what I suggested instead?
the muzzleflash will also sometimes happen on both entities on a shot, despite the function only being run once on PrimaryAttack. When asked to print which gun its on, it will print both 0 and 1 on their own line as if MuzzleEffect was being ran twice. [lua] if CLIENT then local CurGun = 0 function SWEP:MuzzleEffect() if CurGun == 0 then elname = "element_name" elseif CurGun == 1 then elname = "element_name+++++++++" end muzzleflash = EffectData() muzzleflash:SetOrigin(self.VElements[elname].modelEnt:GetPos()+self.VElements[elname].modelEnt:GetAngles():Up()) muzzleflash:SetAngles(self.Owner:GetAimVector():Angle()) muzzleflash:SetScale(2) if CurGun == 1 then CurGun = 0 elseif CurGun == 0 then CurGun = 1 end util.Effect("MuzzleEffect", muzzleflash) end end [/lua] [editline]9th September 2013[/editline] [QUOTE=_Kilburn;42129277]That's the problem I was talking about earlier. You need to attach the muzzle effect to something so you can have control over its position. Did you try what I suggested instead?[/QUOTE] I will right now, give me a sec.. [editline]9th September 2013[/editline] Alright, With just the entity defined the effect does not appear. If i set the origin to the position of the same entity it will give the same results as Grobov's solution. AKA, the flashes still do not tie to the entity.
[QUOTE=Archemyde;42129326]the muzzleflash will also sometimes happen on both entities on a shot, despite the function only being run once on PrimaryAttack. When asked to print which gun its on, it will print both 0 and 1 on their own line as if MuzzleEffect was being ran twice.[/QUOTE] [lua]if IsFirstTimePredicted() then CurGun = 1 - CurGun end[/lua] The problem probably comes from the fact that clientside prediction causes PrimaryAttack to be called multiple times clientside when you shoot once. To fix that, you can use IsFirstTimePredicted to perform some operations only once. [QUOTE=Archemyde;42129326]Alright, With just the entity defined the effect does not appear. If i set the origin to the position of the same entity it will give the same results as Grobov's solution. AKA, the flashes still do not tie to the entity.[/QUOTE] MuzzleEffect probably takes a position and doesn't attach itself to an entity then. Try the effects you've used previously, like ChopperMuzzleFlash or AirboatMuzzleFlash.
[QUOTE=_Kilburn;42129968][lua]if IsFirstTimePredicted() then CurGun = 1 - CurGun end[/lua] The problem probably comes from the fact that clientside prediction causes PrimaryAttack to be called multiple times clientside when you shoot once. To fix that, you can use IsFirstTimePredicted to perform some operations only once. MuzzleEffect probably takes a position and doesn't attach itself to an entity then. Try the effects you've used previously, like ChopperMuzzleFlash or AirboatMuzzleFlash.[/QUOTE] Neither work. only MuzzleEffect seems to even show up. IsFirstTimePredicted() fixed my problem right away with the double calls. I didn't know that about clientside calls, That's really strange. You'd think that shouldn't happen in most cases. So now we're just down to binding the muzzleflash to the entities to move with them. Also, thank you for all the help so far, i've been learning alot from all this.
bump, still attempting to bind these effects to their proper positions so they move with the viewmodel
Sorry, you need to Log In to post a reply to this thread.