How to use Zblox’s Placement Module [OLD]

Notice

This module uses deprecated code and is no longer being updated. For a system that is being actively updated, please use this tutorial instead: https://devforum.roblox.com/t/how-to-use-placement-service

Zblox’s placement module (V2) tutorial

Hello! In this tutorial, I will show you how to use my placement module that I have been working on. This includes:

  • How to set up your game to work easily with the module,
  • How to build models with primary parts
  • How to trigger placement,
  • How to finish placement using a remote event,
  • Editing settings to further customize the module.
  • Limitations

The first thing you will need, is to get the module from the catalog. Once you have that, we can move on (keep in mind, this module is used for sandbox tycoon games)!

Setting up your game!

Now, this is not required to work, but I recommend first time users to use this setup.

Insert a model or folder into the workspace, and call it Plots. Then add a model call it Plot, and put a folder and a part in inside it. Call the part Plot and the folder PlacedObjects (or something like that). After your done, it should look something like this:

image1

Let’s scale the Plot part to 180 (x), 1 (y), 180 (z) and place it on top of the baseplate. Make sure you anchor it!
Next, we will wan’t to get the module in our game. Add in a folder called modules and put in ReplicatedStorage. Next, put the module in there. We will also want a folder for models and remote events.
It should look something like this:

image2

Now we will add a remote event in the Events folder. I called mine PlaceObj since that is what we will be using it for. In StarterGui, add a ScreenGui, and make any sort of UI interface you want. I just have a simple text button with a few changes in the properties menu. I named it Trigger. Now you wan’t to add a LocalScript in the ScreenGui. Name it ClientPlacement since that is what it is.

Here is my setup for the UI:

The final thing for setup is to add a server side script in ServerScriptService and call it ServerPlacement.
Great!

Building models

This is one of the most important parts of this tutorial. To start off, you are going wan’t to build on the grid texture you choose.

This is to ensure the model will snap to the grid when you are moving the model around. This is mainly for the primary part.

Primary Parts

The primary part is the object that the model snaps to the grid with. To make this, first group your item into a model and name it whatever you like. Click on the model and in properties you will see PrimaryPart as a setting. Before we set this, we need to create the PrimaryPart. You can build this however you want just make sure it covers the box the model creates on the x and z coordinates.

image5

Next, put this part in the model and set it as the primary part by clicking primary part on the model and then clicking on the part you wan’t to be the primary part. Once your done, place the model on top of your plot and then put it in that models folder we created.

Triggering placement

In that ClientPlacement script, we will be doing some work here. Make variables for ReplicatedStorage, Players and the module.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local placementModule = require(ReplicatedStorage.Modules.PlacementModuleV2)

local trigger = script.Parent.Trigger

Next, detect when the button is clicked, and invoke the function new().

trigger.MouseButton1Click:Connect(function()
    placementModule:new()
end)

In the new() function there are a few things we need to feed it.

  1. string Model name,
  2. obj Models location (where they are located),
  3. obj The plot location (the part you want the texture to be shown on),
  4. obj Location where the objects are going to end up once placed,
  5. bool Toggle stackable objects,
  6. bool Rotation type (I will let you play with this instead of me explaining this).

I will make variables for some of these things so the line does not get too long.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local placementModule = require(ReplicatedStorage.Modules.PlacementModuleV2)

local trigger = script.Parent.Trigger
local plot = game.Workspace.Plots.Plot.Plot -- added
local placedObjects = game.Workspace.Plots.Plot.PlacedObjects -- added
local models = ReplicatedStorage.Models -- added

trigger.MouseButton1Click:Connect(function()
    placementModule:new()
end)

Let’s give the function it’s fuel!

trigger.MouseButton1Click:Connect(function()
     placementModule:new("Chair", models, plot, placedObjects, false, false) -- edited
end)

This will let you move the object around while using all the controls. Now we need placement!

Placing down objects

Staying in the same script, we need to make a few more variables for the player, mouse and the remote event.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local placementModule = require(ReplicatedStorage.Modules.PlacementModuleV2)

local trigger = script.Parent.Trigger
local plot = game.Workspace.Plots.Plot.Plot
local placedObjects = game.Workspace.Plots.Plot.PlacedObjects
local models = ReplicatedStorage.Models
local remote = ReplicatedStorage.Events.PlaceObj -- added
local player = Players.LocalPlayer -- added
local mouse = player:GetMouse() -- added

trigger.MouseButton1Click:Connect(function()
    placementModule:new("Chair", models, plot, placedObjects, false, false)
end)

Now we need to detect when the mouse button is clicked. We will also invoke a function called Finish(). This will place the object down onto the desired location.

mouse.Button1Down:Connect(function()
    placementModule:Finish()
end)

In the Finish() function, all you need to give it is the remote event.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local placementModule = require(ReplicatedStorage.Modules.PlacementModuleV2)

local trigger = script.Parent.Trigger
local plot = game.Workspace.Plots.Plot.Plot
local placedObjects = game.Workspace.Plots.Plot.PlacedObjects
local models = ReplicatedStorage.Models
local remote = ReplicatedStorage.Events.PlaceObj
local player = Players.LocalPlayer
local mouse = player:GetMouse() 

trigger.MouseButton1Click:Connect(function()
    placementModule:new("Chair", models, plot, placedObjects, false, false)
end)
mouse.Button1Down:Connect(function()
     placementModule:Finish(remote) -- edited
end)

This completes the client side of the system.

Server side

In the server script we created, we need to listen for the remote event to be fired.

local function Place(plr) -- plr is passed automatically
	
end

game.ReplicatedStorage.Events.PlaceObj.OnServerEvent:Connect(Place)

The remote event gives us all the information needed to find and place the object.

  1. Player

  2. The data for the model name and rotation,

  3. The location of where the model is to be placed,

  4. The position.

    local function Place(plr, data, location, pos) -- edited
     
    end
    
    game.ReplicatedStorage.Events.PlaceObj.OnServerEvent:Connect(Place)
    

Using this data we can get the model and set the appropriate properties.

local function Place(plr, data, location, pos)
    local model = game.ReplicatedStorage.Models:FindFirstChild(data.Name):Clone() -- added
	
	model.PrimaryPart.Transparency = 1 -- added
	model.PrimaryPart.CanCollide = false -- added
end

game.ReplicatedStorage.Events.PlaceObj.OnServerEvent:Connect(Place) 

The last thing is to set the position of the model using CFrames and set the parent.

local function Place(plr, data, location, pos)
    local model = game.ReplicatedStorage.Models:FindFirstChild(data.Name):Clone() -- added
	
	model.PrimaryPart.Transparency = 1
	model.PrimaryPart.CanCollide = false

    model:SetPrimaryPartCFrame(CFrame.new(pos.X, pos.Y, pos.Z) * CFrame.Angles(0, math.rad(data.CFrame.Rotation), 0)) -- added

    model.Parent = location -- added
end

game.ReplicatedStorage.Events.PlaceObj.OnServerEvent:Connect(Place) 

That’s it! Now we can move, rotate and place down objects!

Customizing placement

To further customize your placement system, you can edit the settings in the module. I will go over them all right now.

  1. bool MoveByGrid. This controls if you want the model to move by a grid,
  2. int GridSize. The grid that the model moves by,
  3. bool DisplayGrid. If you wan’t to show a grid while placing,
  4. bool SmartDisplay. This will make the grid rescale depending on the grid size,
  5. string GridTexture. The texture you wan’t to show when placing the model,
  6. bool Interpolate. This smooths the movement and rotation,
  7. number InterpolateSpeed. The speed of the interpolation (a value from 0, 1) 0 = instant,
  8. int RotationStep. How many degrees the model will rotate when you press the rotate key,
  9. int FloorStep. How many studs the model will move up/down when you toggle the floor keys,
  10. int MaxHeight. The maximum height the model can reach,
  11. number CollisionCheckCooldown. The cool down before placing down the object to ensure the models collision state,
  12. bool DetectCollisions. This toggles collision detection,
  13. bool IgnoreItems. If you wan’t the mouse to ignore everything else placed on the plot,
  14. bool BuildModeEnabled. This will not stop placement until the cancel key is placed,
  15. bool EnableFloors. This toggles the floor system,
  16. bool TransparentModels. This edits the models transparency when placing,
  17. Color3 CollisionColor. Color of the models primary part when colliding with another model/object,
  18. Color3 PlacingColor. Color of the models primary part when not colliding,
  19. KeyCode KeyCodeCancel. Key needed to be pressed to cancel placement,
  20. KeyCode KeyCodeRotate. Key needed to be pressed to rotate the model,
  21. KeyCode KeyCodeRaiseFloor. Key needed to be pressed to raise the floor,
  22. KeyCode KeyCodeLowerFloor. Key needed to be pressed to lower the floor.

Other settings

  1. number transparentDelta. The change in transparency if TransparentModels is enabled,
  2. number hitboxTransparency. The transparency of the models primary part when placing,
  3. number step. If stacking is enabled, the step is used to correct the models y pos.

These settings total to 25 including the “other ones”. These can make a quite unique placement system.

Limitations

Now, there are some big limits on this modules current state. One main one being it cannot be used for mobile or consoles (yet). It’s also not meant to be used for anything other than sandbox tycoons. One last one being you have to follow a couple steps to make grid snapping work perfectly.

  • The plot has to be a multiple of your grid size,
  • The grid size should (in most cases) be an even number (no decimals)

More info

I am still working on this module to add more functionality so suggestions would help. I don’t require any credit to use in a game, but you can if you want.

Anyway, here’s a video showing the module in action!

A test place was linked here before. It has been removed due to the module being outdated. Please see the link at the top to go to the current module tutorial. There is a link to test that module at the end.

Good luck!

62 Likes

Wow - that a piece of kit this is Xblox! Thank you for this super thorough write up about it too. So often you see a plugin with an interesting title and you think, ooh what’s this really about? Only to find that there is nothing in the description!
Well done!!

3 Likes

This kit looks exciting, I have made my own an Placement System, but It’s not that complex, but keep up the good work!

1 Like

How is this different from Creating A Furniture Placement System

Does it have any pros and cons over the other one?

I’m not trying to be rude but I need to know why I should use your Module rather than one made by an experienced and well known Developer, I’ll definitely use it if it’s better

2 Likes

I have not used this module, but looking at the OP it seems like it’s more for ppl who dont want to build their own placement system. It seems to be well documented and have a lot of flexibility and polish in its features making it useful for many different situations

My post is more about explaining how you would create a placement system and is very barebones in that it covers the essentials.

So really, even though im not the op, I can still answer this. Its because they’re aimed at two completely different audiences.

6 Likes

The main pro to this module to that is this easier to use (I think). It also contains some settings that I did not see in that placement system (interpolation and others). Now, of course you could add these features in that one, but this module handles those already.

2 Likes

Looks like a great module. I would suggest posting an editable sample place, so that people can easily try out your module and play around with it.

1 Like

The new method is somewhat awkward for me, because I’m used to new being an object constructor for a class and this uses a colon to call the method rather than a dot.

Kudos to you for making a module to facilitate object placement, all things aside. Building games seem to be gaining more traction on Roblox so having a way to ease into it seems very helpful.

2 Likes

I will change this to something else. To be honest, I didn’t really put time into the names of the two functions discussed in this tutorial. I will update them.

Ok, I will do that as soon as possible!

1 Like

I added this into the post based on your feedback.

1 Like

Wow! I’ve never needed to make/use a placement system, although there are a few modules out there already that would have done the job if I had needed them to. However, this module is very flexible and has many more configuration options than some of the others I’ve looked at. Very good job with this. :smiley:

1 Like

The keycode functionality seems like something that should be implemented by the module user and not internally since people might also do it by UI. Should probably leave it to just functions the user can call to trigger such operations.

1 Like

Sorry for bumping, but how would I implement saving into the system?

That seems out of scope of this module, so you’ll probably want to try your hand at it yourself and then use #help-and-feedback:scripting-support to ask specific questions when you get stuck.

2 Likes

How would I make it so you cant place models outside of the base part.

Technically, this is not built in to the module… I have a sandbox series on my YouTube channel that shows the work around. You can look at that here. No I am not proud of this solution, but there is no math involved!

a question you can use any item

this module is outdated. Please use my newer module