- Home /
How to make Minecraft fences?
What I want to do is like the fences of minecraft when you put 1 a fence is created but when you put another one aside it is completed automatically and I tried with all collider and it does not come out. I have tried everything but I do not get the truth, I would like to know opinions or any documentation that you have would be very helpful`enter code here`
public enum FencePosition { Up = 0, Down = 1 << 0, Right = 1 << 1, Left = 1 << 2 }
public static class FencePositionExtension { public static FencePosition GetOpposite(this FencePosition position) { var oppositePosition = FencePosition.Up;
if (position == FencePosition.Up)
{
oppositePosition = FencePosition.Down;
}
else if (position == FencePosition.Down)
{
oppositePosition = FencePosition.Up;
}
else if (position == FencePosition.Left)
{
oppositePosition = FencePosition.Right;
}
else if (position == FencePosition.Right)
{
oppositePosition = FencePosition.Left;
}
return oppositePosition;
}
}
public class Fence : MonoBehaviour { public GameObject up; public GameObject down; public GameObject left; public GameObject right;
public void SetPlank(FencePosition position, bool value)
{
switch (position)
{
case FencePosition.Up:
this.up.SetActive(value);
break;
case FencePosition.Down:
this.down.SetActive(value);
break;
case FencePosition.Right:
this.right.SetActive(value);
break;
case FencePosition.Left:
this.left.SetActive(value);
break;
default:
break;
}
}
}
Answer by henkehedstrom · Jan 07 at 10:55 AM
I am not really sure if I understand what you want to achieve with your code but I would do something like this:
Create two prefabs, one with just the vertical stick (like in your fence.png picture) and then one prefab with the horizontal lines. If you place a fence down next to another fence piece, you check if it is above or under that fence piece. If so, you don't have to do anyhting because they will align properly. If it is to some of the sides of the fence you check which side and then place the horizontal stick prefab on that side of the first fence object.
So if I have one fence piece placed down that we call A and then we place another called B to the right of the A object. Then A will notice that another fence object was created to the right of itself and it would instantiate the horizontal prefab to the right of itself.
I don't know how you have done the placement and such in your project so it might not work like this but if you know that a fence is colliding with another you could compare positions to figure out on what side the other fence piece is at.
Answer by Bunny83 · Jan 07 at 01:36 PM
Well, we know nothing about your game or how your world is contructed. Minecraft is a voxel based game. So the whole terrain is based on a 3d grid. The whole terrain mesh (which is split in chunks) is generated procedurally. The connecting fence bars are simply generated for a fence voxel if the neighboring block is solid. So this is an inherent property of the fence voxel when it generates its mesh.
Is your game at least grid based? Note that the fence bars are actually split in half, so they end at the block border So two fences next to each other would connect their fence bars naturally. A fence block does update its state when it receives a block update. In that case it simply scans the 4 neighboring blocks and if they are solid, it generates fence bars on that side.
Hopefully you know that you can not create a Minecraft like game out of individual meshes and gameobjects for each block or even sub blocks. This would result in millions of gameobjects which Unity and your PC can't handle. You have to create mesh chunks. Of course if you're not creating a minecraft like game, there may be other solutions, however as I said in the beginning, we know nothing about your game at the moment.
A quick note on your code: Your "FencePosition" enum looks like it's supposed to be a bit mask but that wouldn't make much sense since your "Up" entry is 0. At the moment your entries have the values:
Up = 0
Down = 1
Right = 2
Left = 4
As I said that doesn't make much sense. Either it's a bitmask, then the first entry has to start with 1, or it's just a normal enumeration in which case the whole bitshifting doesn't make much sense. So either define it as
Up = 0
Down = 1
Right = 2
Left = 3
or as
Up = 1<<0 // 1
Down = 1<<1 // 2
Right = 1<<2 // 4
Left = 1<<3 // 8
Another thing that seems a bit confusing is your naming of those entries. Is your game 2d or 3d? If it's 3d (since you said minecraft like) the terms up and down would be ultra confusing if those specify horizontal directions. Terms like left and right depends on the perspective. That's why using north, east, south and west makes more sense for the horizontal directions and up / down for the vertical. Though, again we simply don't know enough about your game.
oh I see Bunny83 I did not explain very well I have a 3D grid and to instantiate the fence I use a raycast that I compare with a label called ground and if it is true I instantiate the fence I just want the fence to know if there is another fence in front, of it as top down, right, left, the fence is divided with 5 prefabs as center top bottom right left what I try to do is like the video please if you can see it is 31 seconds https://www.youtube.com/watch?v=OuhvQElCjBA and I tried to use Physics.SphereCast or also a Physics.OverLapSphere but it would not give a good performance
Answer by MGUELfig189 · Jan 08 at 07:48 PM
oh I see @Bunny83 @henkehedstrom I did not explain very well I have a 3D grid and to instantiate the fence I use a raycast that I compare with a label called ground and if it is true I instantiate the fence I just want the fence to know if there is another fence in front, of it as top down, right, left, the fence is divided with 5 prefabs as center top bottom right left what I try to do is like the video please if you can see it is 31 seconds https://www.youtube.com/watch?v=OuhvQElCjBA and I tried to use Physics.SphereCast or also a Physics.OverLapSphere but it would not give a good performance
If you have it in a grid you should now what index the fence has in that grid. Then you should be able to loop through the fence's neighbours. I have never worked with a 3d grid but I bet there is a lot of examples online on how to do that. Then you have to loop trough 27 cells and first check if the cell is empty or not and then check if it is a fence. If it is a fence you should return what kind of neighbour it is. I am not sure if this will be faster but that is a way that you could do it without raycasts and overlap spheres.
Another potential solution would be to have a big collider on the fence that would be big enough so it would detect a fence in a neighboring cell. You could change some of the physics layer collision matrix so that collider would only collide with fences. This is very specific for fences then but it might be of help.