Search code examples
luaentitygarrys-mod

How can I attach multiple models to an entity in Garry's Mod?


I want to make a scripted entity that looks like the left side of this picture, combining several models together: the equipment rack, computer screen, keyboard, battery, etc.

I want to do this with Lua scripting, not by using Blender to merge all these models together into one.

How can I do this?

Left: several Half-Life 2 models arranged together to create a more complex object. Right: the base model by itself.


Solution

  • If you have two distinct models :

    • models/machine/machime.mdl
    • models/rack/rack.mdl

    You can then create two entities :

    1. The machine entity

      1.1 lua/entities/machine/init.lua

    AddCSLuaFile( "cl_init.lua" )
    AddCSLuaFile( "shared.lua" )
    
    include('shared.lua')
    
    function ENT:Initialize()
       self:SetModel("models/machime/machime.mdl")
       self:PhysicsInit(SOLID_VPHYSICS)
       self:SetMoveType(MOVETYPE_VPHYSICS)
       self:SetSolid(SOLID_VPHYSICS)
    
       local phys = self:GetPhysicsObject()
    
       if phys:IsValid() then
          phys:Wake()
       end
    end
    
    

    1.2 lua/entities/machine/cl_init.lua

    include('shared.lua')
    
    function ENT:Draw()
      self:DrawModel()
    end
    

    1.3 lua/entities/machine/shared.lua

    ENT.Type = "anim"
    ENT.Base = "base_gmodentity"
    
    ENT.AdminOnly   = false
    ENT.Spawnable   = true
    ENT.PrintName   = "My machine"
    ENT.Purpose     = "This is a really good machine"
    
    1. The rack entity

      2.1 lua/entities/rack/init.lua

    AddCSLuaFile( "cl_init.lua" )
    AddCSLuaFile( "shared.lua" )
    
    include('shared.lua')
    
    function ENT:Initialize()
       self:SetModel("models/rack/rack.mdl")
       self:PhysicsInit(SOLID_VPHYSICS)
       self:SetMoveType(MOVETYPE_VPHYSICS)
       self:SetSolid(SOLID_VPHYSICS)
    
       local phys = self:GetPhysicsObject()
    
       if phys:IsValid() then
          phys:Wake()
       end
    end
    
    

    2.2 lua/entities/rack/cl_init.lua

    include('shared.lua')
    
    function ENT:Draw()
      self:DrawModel()
    end
    

    2.3 lua/entities/rack/shared.lua

    ENT.Type = "anim"
    ENT.Base = "base_gmodentity"
    
    ENT.AdminOnly   = false
    ENT.Spawnable   = true
    ENT.PrintName   = "My rack"
    ENT.Purpose     = "To rack them all"
    

    Finally to put the rack in the machine you can use ENT:SetParent :

    local machine = ents.Create("machine") -- create a new machine entity
    machine:SetPos(THE_POSITION) -- change the position of spawn
    machine:Spawn() -- spawn it
    
    local rack = ents.Create("rack") -- create a rack entity
    rack:SetParent(machine) -- set the parent to machine
    rack:SetLocalPos(THE_LOCAL_POS) -- where the rack is relative to the machine
    rack:Spawn() -- spawn it
    

    Note : In the last part the example spawn and put the rack in the machine. You could also use the ShouldCollide hook to put the rack in the machine when they'r about to collide !