Garry's Mod Wiki

Revision Difference

Entity:GetAttachment#528276

<function name="GetAttachment" parent="Entity" type="classfunc"> <description> Gets the orientation and position of the attachment by its ID, returns nothing if the attachment does not exist. <note>The update rate of this function is limited by the setting of ENT.AutomaticFrameAdvance for <page>Scripted Entities</page>!</note> <bug issue="1255">This will return improper values for viewmodels if used in <page>GM:CalcView</page>.</bug> </description> <realm>Shared</realm> <args> <arg name="attachmentId" type="number">The internal ID of the attachment.</arg> </args> <rets> <ret name="" type="table">The angle and position of the attachment. See the <page>Structures/AngPos</page>. Most notably, the table contains the keys "Ang" and "Pos".</ret> </rets> </function> <example> <description>Grabs the muzzle position of a player's view model.</description> <code> local vm = ply:GetViewModel() local obj = vm:LookupAttachment( "muzzle" ) if (obj < 1) then local muzzle = vm:GetAttachment( obj ) print( muzzle.Pos, muzzle.Ang ) end </code> </example> <example> <description>Draws a green cube at the player's view model muzzle if the model has a "muzzle" attachment. This properly translates the attachment into the view model projection space.</description> <code> -- FIXME: The nFOV parameter should be replaced with ViewModelFOV() when it's binded local function FormatViewModelAttachment(nFOV, vOrigin, bInverse --[[= false]]) local function FormatViewModelAttachment(nFOV, vOrigin, bFrom --[[= false]]) local vEyePos = EyePos() local aEyesRot = EyeAngles() local vOffset = vOrigin - vEyePos local vForward = aEyesRot:Forward() local nViewX = math.tan(nFOV * math.pi / 360) if (nViewX == 0) then vForward:Mul(vForward:Dot(vOffset)) vEyePos:Add(vForward) return vEyePos end -- FIXME: LocalPlayer():GetFOV() should be replaced with EyeFOV() when it's binded local nWorldX = math.tan(LocalPlayer():GetFOV() * math.pi / 360) if (nWorldX == 0) then vForward:Mul(vForward:Dot(vOffset)) vEyePos:Add(vForward) return vEyePos end local nFactor = nWorldX / nViewX⤶ local vRight = aEyesRot:Right()⤶ local vRight = aEyesRot:Right()⤶ local vUp = aEyesRot:Up() if (bInverse) then vRight:Mul(vRight:Dot(vOffset) / nFactor)⤶ vUp:Mul(vUp:Dot(vOffset) / nFactor) if (bFrom) then local nFactor = nWorldX / nViewX⤶ vRight:Mul(vRight:Dot(vOffset) * nFactor) vUp:Mul(vUp:Dot(vOffset) * nFactor)⤶ else local nFactor = nViewX / nWorldX⤶ vRight:Mul(vRight:Dot(vOffset) * nFactor) vUp:Mul(vUp:Dot(vOffset) * nFactor) end vForward:Mul(vForward:Dot(vOffset)) vEyePos:Add(vRight) vEyePos:Add(vUp) vEyePos:Add(vForward) return vEyePos end SWEP.BoxAttachment = "muzzle" SWEP.BoxMins = Vector(-2, -2, -2) SWEP.BoxMaxs = Vector(2, 2, 2) SWEP.BoxColor = Color(0, 255, 0) function SWEP:ViewModelDrawn() local pOwner = self:GetOwner() if (not pOwner:IsValid()) then return end local pViewModel = pOwner:GetViewModel() if (not pViewModel:IsValid()) then return end local uAttachment = pViewModel:LookupAttachment(self.BoxAttachment) if (uAttachment < 1) then return end local tAttachment = pViewModel:GetAttachment(uAttachment) if (tAttachment == nil) then return end -- FIXME: This should be removed when ViewModelFOV() is binded local nFOV = self.ViewModelFOV if (not isnumber(nFOV)) then nFOV = 62 end render.DrawWireframeBox(FormatViewModelAttachment(nFOV, tAttachment.Pos, true), tAttachment.Ang, self.BoxMins, self.BoxMaxs, self.BoxColor, true) render.DrawWireframeBox(FormatViewModelAttachment(nFOV, tAttachment.Pos, false), tAttachment.Ang, self.BoxMins, self.BoxMaxs, self.BoxColor, true) end </code> </example>