• Hats: Server or Client side?
    16 replies, posted
Ok, so my experience with putting hats on player models has been terrible, to say the least. It seems that no matter what I do, I can't get them to work exactly right. Either they don't spawn at all, they spawn like mid-game, or they spawn on some people, but not on others and then disappear when people die. Here's an example thing I installed on my server: [url]http://www.garrysmod.org/downloads/?a=view&id=85708[/url] When I put this on my server, (I edited it for FastDL and I put the entity correctly into the gamemode I use) The hats didn't show up except on ONE person and then after that they didn't work. WTF?! So my question is, is it better to use server-side or client-side LUA to set the hats positions and shit? Or can someone supply me with a hat code that appears INSTANTLY when someone respawns? Thanks for any help you can give me.
Alright thanks, I'll try that method out.
Ok, here's my code: [lua] function DrawSantaHat() for k, pl in pairs( player.GetAll() ) do -- Draw on all players. if pl:GetRagdollEntity() then -- Don't draw on dead players without ragdolls OldSanta = pl.santa pl = pl:GetRagdollEntity() pl.santa = OldSanta end local boneindex = pl:LookupBone("ValveBiped.Bip01_Head1") if boneindex then local pos, ang = pl:GetBonePosition(boneindex) if pos and pos != pl:GetPos() then if !pl.santa then pl.santa = ClientsideModel( "models/santa/santa.mdl", RENDERGROUP_OPAQUE ) -- Thanks iRzilla for the tip on ClientsideModel() for hats. end if LocalPlayer():GetModel() == "models/player/guerilla.mdl" then pl.santa:SetModelScale(Vector(1,.9,1.1)) pl.santa:SetPos(pos + ang:Forward()*2.5 + ang:Right()*-1.8) -- Positioning else pl.santa:SetModelScale(Vector(1.1,.9,1.1)) pl.santa:SetPos(pos + ang:Forward()*3 + ang:Right()*-1.7) -- Positioning end ang:RotateAroundAxis(ang:Right(), 270) ang:RotateAroundAxis(ang:Up(), 270) pl.santa:SetAngles(ang) if pl == LocalPlayer() then pl.santa:SetColor( 0, 0, 0, 0 ) -- Make invisible so it doesn't block view. else pl.santa:SetColor( 255, 255, 255, 255 ) end pl.santa:DrawModel() return end local attach = pl:GetAttachment(pl:LookupAttachment("eyes")) if not attach then attach = pl:GetAttachment(pl:LookupAttachment("head")) end if attach then pl.santa:SetPos(attach.Pos) pl.santa:SetAngles(attach.Ang) pl.santa:DrawModel() end end end end hook.Add( "Tick", "SantaHat", DrawSantaHat ) [/lua] It's included in my gamemode and everything and it works in single player but it's not working on my server. It's not drawing the hats on anyone and I am getting no errors. Could it be due to the fact that my server has over 20 people in it? Or, is it something else in my code?
I highly suggest not using tick like that, nor applying them using a loop, as for this type of thing there are at least a couple of other options with more benefits. [QUOTE=iRzilla;19096577]Use a ClientsideModel() and parent it to the players head. Otherwise the server has to send the position of the hat everytime a player moves.[/QUOTE] This also isn't true. You can parent the model, and network the positions perfectly fine, with no delay, as you can always set up situations where these things can be predicted, however, you will want to stick to parenting on the client-side, I just wanted to clarify this, just in case you do decide to make it server-side for it's other benefits. In conclusion, simply parent the model on spawn, and parent it again on death to the Player.GetRagdollEntity. This would be the best way to do it, considering you're making it seem as an extension to their body. Then, you won't have to deal with any networking in between.
Holy shit, no, never, you should never ever draw anything in Tick or Think. If you really want to use gamemode hooks, use something like RenderScreenspaceEffects. Or just make your hats entities, parent them to players, and do the rendering clientside.
RenderScreenspaceEffects is for post-processing, not for this. And I beg to differ, you can draw perfectly fine with those two hooks, but this isn't an instance where you should.
You should use PostDrawOpaqueRenderables.
Why?
Andrew by parenting do you mean self.Entity:SetParent( pl ) or all of the actual positioning on the player's head? I'm kind of confused and if you can give an example code it would be helpful.
[QUOTE=cheiftiger;19107342]Andrew by parenting do you mean self.Entity:SetParent( pl ) or all of the actual positioning on the player's head? I'm kind of confused and if you can give an example code it would be helpful.[/QUOTE] I suggest [url=http://developer.valvesoftware.com/wiki/Entity_Hierarchy_%28parenting%29#SetParentAttachmentMaintainOffset][B]SetParentAttachmentMaintainOffset[/B][/url]. Use it with [url=http://wiki.garrysmod.com/?title=Entity.Fire][B]ent:Fire()[/B][/url].
[QUOTE=Aska49;19107825]I suggest [url=http://developer.valvesoftware.com/wiki/Entity_Hierarchy_%28parenting%29#SetParentAttachmentMaintainOffset][B]SetParentAttachmentMaintainOffset[/B][/url]. Use it with [url=http://wiki.garrysmod.com/?title=Entity.Fire][B]ent:Fire()[/B][/url].[/QUOTE] That's serverside, it won't work on player ragdolls. Also, it relies on attachment, if a model doesn't have a proper head attachment, it won't work at all. [QUOTE=andrewmcwatters;19107186]RenderScreenspaceEffects is for post-processing, not for this. And I beg to differ, you can draw perfectly fine with those two hooks, but this isn't an instance where you should.[/QUOTE] Are you really sure? A bunch of hooks are called in a given context which makes them behave differently. You can't draw anything in an entity's Think hook, because it won't render anything at all. Also, Think and Tick aren't called every frame.
That's very true. In fact, I'm backing your claim right now by using Move to do this. It also allows me to point out the player without using a loop. [editline]03:06PM[/editline] [lua] local function PlayerWearHat( ply ) local boneindex = ply:LookupBone( "ValveBiped.Bip01_Head1" ) if ( !boneindex ) then return end local bonepos, boneang = ply:GetBonePosition( boneindex ) boneang:RotateAroundAxis( boneang:Up(), 180 ) boneang:RotateAroundAxis( boneang:Right(), 90 ) if ( !ply.m_hHat ) then ply.m_hHat = ClientsideModel( "models/Effects/bday_hat.mdl", RENDERGROUP_OPAQUE ) ply.m_hHat:SetParent( ply ) ply.m_hHat:Spawn() else local m_bNoDraw if ( GetViewEntity() != LocalPlayer() ) then m_bNoDraw = false else m_bNoDraw = true end ply.m_hHat:SetNoDraw( m_bNoDraw ) ply.m_hHat:SetPos( bonepos + boneang:Up() * 7.0 ) ply.m_hHat:SetAngles( boneang ) end end hook.Add( "Move", "PlayerWearHat", PlayerWearHat ) [/lua] [editline]03:10PM[/editline] [media]http://img.photobucket.com/albums/v308/flaming-gummy-bear/gm_flatgrass0001-1.jpg[/media]
[QUOTE=iRzilla;19124089]What's the point in creating a extra entity for the server when it can be done clientside with a CSent eh? Decoration should be done clientside.[/QUOTE] I agree, anything that has no physics and is not required to be used ever by the server, please use everything clientside and save everyone the lag. Any kind of custom parenting should happen in a Draw hook before self.Entity:DrawModel() is called, otherwise you'll get some positioning lag. The Hat Maker addon does all of this very poorly, and uses an amazingly stupid amount of NWVars for something that should be fully clientside. [editline]02:01PM[/editline] Screw it, I'm making my own "Hat Maker" for developers since I can't model and this is the next best thing.
[QUOTE=_Kilburn;19108022]Also, it relies on attachment, if a model doesn't have a proper head attachment, it won't work at all.[/QUOTE] Which would never happen unless both the modeller and scripter are also lacking proper head attachments.
[QUOTE=Nerdeboy;19132970]Which would never happen unless both the modeller and scripter are also lacking proper head attachments.[/QUOTE] Sometimes it's called head, others you have to use eyes. It's not consistent, even with Valve.
Sorry, you need to Log In to post a reply to this thread.