// 隣のブロックとの閉塞チェック private bool IsOcculuded(BlockGroup group, BlockDirection direction) { int dirIndex = (int)direction; // 隣のブロックに完全に覆われていたら省略する(閉塞チェック) Block neighborBlock = group.GetBlock(this.position + EditManager.Instance.ToWorldCoordinate(neighborOffsets[dirIndex])); if (neighborBlock != null) { var con1 = this.GetConnection((BlockDirection)(dirIndex)); var con2 = neighborBlock.GetConnection((BlockDirection)(dirIndex ^ 1)); if (con2 == BlockConnection.None) { return(false); } else if (con2 == BlockConnection.Square) { return(true); } else if (con1 == con2) { var dir1 = this.GetConnectionDir((BlockDirection)(dirIndex)); var dir2 = neighborBlock.GetConnectionDir((BlockDirection)(dirIndex ^ 1)); if (dir1 == dir2) { return(true); } } } return(false); }
public bool CanMoveTo(FieldPanel target, BlockGroup blockGroup) { bool movable = true; if (target.position.y == this.position.y) { // 同じ高さのパネル } else if (target.position.y > this.position.y) { // 上の方のパネル float dy = target.originalPosition.y; float sy = this.originalPosition.y; for (float j = sy + 0.5f; j <= dy + 1.5f; j += 0.5f) { Block block = blockGroup.GetBlock( new Vector3(this.originalPosition.x, j, this.originalPosition.z)); if (block != null) { movable = false; break; } } } else if (target.position.y < this.position.y) { // 下の方のパネル float dy = target.originalPosition.y; float sy = this.originalPosition.y; for (float j = sy + 1.5f; j >= dy + 0.5f; j -= 0.5f) { Block block = blockGroup.GetBlock( new Vector3(target.originalPosition.x, j, target.originalPosition.z)); if (block != null) { movable = false; break; } } } return(movable); }
// 上に4ブロック分のスペースがあるか public bool IsEnterable(BlockGroup blockGroup) { if (this.shape.panelVertices == null) { return(false); } for (int i = 1; i <= 4; i++) { var block = blockGroup.GetBlock(this.position + new Vector3(0, 0.5f * i, 0)); if (block != null) { return(false); } } return(true); }
// 自動配置ブロックの処理 public void WriteToMeshAutoPlacement(BlockGroup blockGroup, BlockMeshMerger meshMerger) { BlockShape shape = this.shape; // 隣接ブロックを取得 var list = new Vector3[] { new Vector3(0, 0, 1), new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(-1, 0, 0), new Vector3(1, 0, 1), new Vector3(1, 0, -1), new Vector3(-1, 0, -1), new Vector3(-1, 0, 1), new Vector3(0, 0.5f, 0), new Vector3(0, 0.5f, 1), new Vector3(1, 0.5f, 0), new Vector3(0, 0.5f, -1), new Vector3(-1, 0.5f, 0), }; int pattern = 0; for (int i = 0; i < list.Length; i++) { var block = blockGroup.GetBlock(position + EditManager.Instance.ToWorldCoordinate(list[i])); if (block != null) { pattern |= (1 << i); } } for (int i = 0; i < 4; i++) { bool s1 = (pattern & (1 << (i))) != 0; // 隣接1 bool s2 = (pattern & (1 << ((i + 1) % 4))) != 0; // 隣接2 bool s3 = (pattern & (1 << (i + 4))) != 0; // 斜め隣接 bool s4 = (pattern & (1 << 8)) != 0; // 上隣接 bool s5 = (pattern & (1 << (9 + i))) != 0; // 上横隣接1 bool s6 = (pattern & (1 << (9 + (i + 1) % 4))) != 0; // 上横隣接2 int meshOffset; if (s3) { if (s1 && s2) { meshOffset = (s4 && (s5 || s6)) ? -1 : 0; } else if (s1) { meshOffset = (s4) ? (s5) ? 24 : 32 : 8; } else if (s2) { meshOffset = (s4) ? (s6) ? 28 : 36 : 12; } else { meshOffset = (s4) ? 20 : 4; } } else { if (s1 && s2) { meshOffset = 16; } else if (s1) { meshOffset = (s4) ? (s5) ? 24 : 32 : 8; } else if (s2) { meshOffset = (s4) ? (s6) ? 28 : 36 : 12; } else { meshOffset = (s4) ? 20 : 4; } } if (meshOffset < 0) { continue; } var mesh = shape.meshes[6 + meshOffset + i]; if (mesh == null) { continue; } meshMerger.Merge(mesh, this.position, this.direction, Vector3.one, shape.divideChipVert, this.textureChips[6], 0); } }
// 6方向ブロックメッシュ public void WriteToMeshStandard(BlockGroup blockGroup, BlockMeshMerger meshMerger) { BlockShape shape = this.shape; for (int i = 0; i < shape.meshes.Length; i++) { int index = this.ToLocalDirection(i); var mesh = shape.meshes[index]; if (mesh == null) { continue; } // 隣のブロックに完全に覆われていたら省略する if (i < 6 && this.IsOcculuded(blockGroup, (BlockDirection)i)) { continue; } // 一番下の底面は省略する if ((BlockDirection)i == BlockDirection.Yminus && this.position.y == 0.0f) { continue; } Vector3 position = this.position; Vector3 scale = Vector3.one; // 側面パネルの場合は分割する bool divideChipVert = shape.divideChipVert && i < 6 && (BlockDirection)i != BlockDirection.Yplus && (BlockDirection)i != BlockDirection.Yminus; if (divideChipVert && this.IsCombinable((BlockDirection)i)) { BlockDirection direction = (BlockDirection)i; // 上下に2個続いているブロックをまとめる if (this.position.y - Math.Floor(this.position.y) >= 0.5f) { Block neighborBlock = blockGroup.GetBlock(this.position - new Vector3(0, 0.5f, 0)); if (neighborBlock != null && neighborBlock.IsCombinable(direction) && this.GetTextureChip(direction) == neighborBlock.GetTextureChip(direction)) { divideChipVert = false; position.y -= 0.25f; scale.y = 2.0f; } } else { Block neighborBlock = blockGroup.GetBlock(this.position + new Vector3(0, 0.5f, 0)); if (neighborBlock != null && neighborBlock.IsCombinable(direction) && this.GetTextureChip(direction) == neighborBlock.GetTextureChip(direction)) { if (!neighborBlock.IsOcculuded(blockGroup, direction)) { continue; } } } } meshMerger.Merge(mesh, position, this.direction, scale, divideChipVert, this.textureChips[index], i); } }