Creating A Furniture Placement System

Another question I had:

How would you make it so you could hold the R key and move your mouse left and right to customize the rotation of the model in any degree, instead of being limited to 45/90 degree rotation?

To do this we only really need to adjust and calculate the rotation argument in the :CalcPlacementCFrame() method.

  1. Adjust our rotation key binding such that when holding down the R key we have a boolean that tells us if we should be rotating or not.

  2. If we aren’t rotating we move around the object as per usual. If we are rotating we save the last position our object was placed at and use that as the position of our placement. We’ll call this the pivot point.

  3. We calculate the difference between our mouse and that pivot point and then convert it to the object space of our canvas part’s surface. This ensures that the rotation is relative to what we’re placing on.

  4. With that object space vector we can find the angle of rotation with math.atan2 and update the rotation parameter accordingly.

This is what that looks like:

All the changes are in the ClientPlacement localscript. That should be enough to get you going. Enjoy!

placement rotation.rbxl (25.4 KB)

43 Likes

It shares a great similarity with the option that allows you to move the articles or move them for your home, which means that if it could be useful for future games. Great topic!!

2 Likes

Why does the saving not work?

I downloaded the finished place but I cant get the saving to work.

Edit: I have tried everything but it dosen’t want to save.

5 Likes

You made this 10 times better my dude.

8 Likes

This really is the most thorough explanation of a placing system, thank you so much EgoMoose!
I have got to the stage where I am having difficulty in placing furniture eg a picture frame, on the vertical face ie. a wall. I would really like to be able for it to work seamlessly on walls connecting at different angles. Anyone got any advice?

I greatly appreciate all the help. :slightly_smiling_face:

3 Likes

All the info you need should be in the thread.

  • The placement system.
  • How to put on different faces of a single part.
  • How to use multiple faces.

Its all in the thread whether it be the original post or one of my replies. Good luck!

9 Likes

Ok, that is good to know!

Thank you EgoMoose :slightly_smiling_face:

2 Likes

Hi EgoMoose, it appears the script you posted for the placement system to be used on multiple parts fails to uploaded the saved furniture items. It appears you are missing the fire of the function Placement.fromSerialisation() for the items to load in.

4 Likes

Currently having this same problem and I’m super confused right now. Could you tell me how you got the client to check the collisions? I keep overthinking it and confusing myself.

2 Likes

Thank you for this!! I hope that as developers, we can improve more of the system.

3 Likes

Do you think you could go into more detail on how you got the furniture to only be movable on specific parts? Your reply that seems like it was explaining it is basically a giant wall of code, and on top of that it’s using an OOP approach which I personally find unreadable.

It would be helpful if you could show something that’s more reader-friendly and explains what they heck you’re doing. The cherry on top would be if it were more general. I like the grid-placement but I don’t want to use everything you’ve written here.

9 Likes

Not sure if you figured this out already, but here it is for future people looking at this thread.

The way he was able to make the furniture only move on a specific part(s) was due to the fact that he set the players mouse TargetFilter to the “canvasPart”. Next, he just set the models parent to the target filter.

Mouse = Player:GetMouse()
Mouse.TargetFilter = workspace.CanvasPart
5 Likes

The loading for the more advanced version where you can have multiple canvases does not work. What’s the point of saving the data if you won’t be able to load it. Unless I’m wrong and loading function works, but I honestly have no idea how to specify what exact canvas the model had been placed on and how it will load it ignoring the fact it can be placed on multiple canvases at once. I have tried making it possible but I was kind of met with failure. The saving itself is alright but the loading has a few issues.

6 Likes

Nice tutorial, I will 100% reference this when I will need to make something like this :slight_smile:

2 Likes

One problem I ran into was that when I would save and rejoin, it would actually clone multiple of those models in the same position and the more times I would save and rejoin the more it would clone these models.

2 Likes

How can this be adapted so that the rotation of the object still faces the floor?

4 Likes

what if i want to place on smooth terrain how would i do that?

3 Likes

just use a invisible part as the canvas area

3 Likes

How do you convert Vector2 to Vector3? Also, how do you make objects stack?

4 Likes

Vector2 to Vector3
– I don’t know why you want to achieve this, but here is easy solution
Vector3.new(vec2.x, 0, vec2.y) or Vector3.new(vec2.x, vec2.y, 0)
Object stack
– I assume ‘stack’ that you mean is something like lamp place on the table.
In this example, just make placement canvas as desk surface or hidden canvas on desk surface.
– I assume that later question relate to first one, where extra axis of vector is current ‘height’ of object stack, I don’t recommend to store data that way, I prefer something like this:

"canvas": {
    "item": Furniture:getId("desk"),
    "position": Vector2.new(12, 24),
    "rotation": 90,
    --"__comment": "You can use something like this if you prefer, 'transform: Vector3.new(x, y, rotate)' ",
    "canvas": {
        --[[ 1:]]{
            "item": Furniture:getId("lamp"),
            "position": Vector2.new(0, 0),
            "rotate": 0,
            --"__comment": "canvas: {} --if you want item to place-able to your lamp! Side note, position should relate to it parent not main canvas or world"
        }
    }
}

Do you see that is better to store data object this way than array of vector of x,y,height and if player move table, lamp move too. If player remove table, lamp gone as well. No floating lamp anymore.

I wrote it in JSON format because it is compatibility with Database Datastore, and it also look like Lua table too.

– If you mean building floors, almost same to desk example :

"plot": {
    --[[1: ]]{
        "canvas": {DeskWithLampObj, chairObj}
    },
    --[[2: ]]{
        "canvas": {}
    }
}

If I am wrong with your question, feel free to notice me to correct it.

6 Likes