public static GridColliderPart LineGridColliderPart(GameObject parent, Grid grid, TileInfo tile, int x, int y, int w, int h) { GameObject obj = new GameObject("line"); obj.transform.SetParent(parent.transform); obj.tag = tile.tag; obj.layer = tile.layer; GridColliderPart part = obj.AddComponent <GridColliderPart> (); part.line = obj.AddComponent <EdgeCollider2D> (); part.line.usedByEffector = true; switch (tile.shape) { case TileShape.DOWN_ONEWAY: part.transform.Rotate(Vector3.forward * 180); break; case TileShape.LEFT_ONEWAY: part.transform.Rotate(Vector3.forward * 90); break; case TileShape.RIGHT_ONEWAY: part.transform.Rotate(-Vector3.forward * 90); break; } PlatformEffector2D effector = part.gameObject.AddComponent <PlatformEffector2D> (); effector.surfaceArc = 5; part.shape = tile.shape; part.isVertical = tile.isVertical; part.id = tile.id; part.line.isTrigger = tile.isTrigger; part.bottomLeftX = x; part.bottomLeftY = y; part.SetSize(w, h); return(part); }
public bool Compatible(TileInfo info) { Collider2D collider = (box == null ? (triangle == null ? (line as Collider2D) : (triangle as Collider2D)) : (box as Collider2D)); return(shape == info.shape && gameObject.tag == info.tag && gameObject.layer == info.layer && collider.isTrigger == info.isTrigger); }
public static GridColliderPart TriangleGridColliderPart(GameObject parent, Grid grid, TileInfo tile, int x, int y, int w, int h) { GameObject obj = new GameObject("triangle"); obj.transform.SetParent(parent.transform); obj.tag = tile.tag; obj.layer = tile.layer; GridColliderPart part = obj.AddComponent <GridColliderPart> (); part.triangle = obj.AddComponent <PolygonCollider2D> (); part.shape = tile.shape; part.isVertical = tile.isVertical; part.id = tile.id; part.triangle.isTrigger = tile.isTrigger; part.bottomLeftX = x; part.bottomLeftY = y; part.transform.localPosition = grid.TileSpaceToTransform(x + w / 2f, y + h / 2f); part.SetSize(w, h); return(part); }
public static GridColliderPart CreateColliderPart(GameObject parent, Grid grid, TileInfo info, int x, int y, int w, int h) { switch (info.shape) { case TileShape.FULL: return(BoxGridColliderPart(parent, grid, info, x, y, w, h)); case TileShape.DOWN_LEFT_TRIANGLE: case TileShape.DOWN_RIGHT_TRIANGLE: case TileShape.UP_LEFT_TRIANGLE: case TileShape.UP_RIGHT_TRIANGLE: return(TriangleGridColliderPart(parent, grid, info, x, y, w, h)); case TileShape.DOWN_ONEWAY: case TileShape.UP_ONEWAY: case TileShape.LEFT_ONEWAY: case TileShape.RIGHT_ONEWAY: return(LineGridColliderPart(parent, grid, info, x, y, w, h)); default: return(null); } }
void JoinTriangle(PositionRegionRenderer currentRenderer, TileInfo info, Tile tile, int x, int y) { bool isExpanded = false; int relX = x - currentRenderer.regionX * Grid.REGION_SIZE; int relY = y - currentRenderer.regionY * Grid.REGION_SIZE; if (info.isVertical) { GridTriangle down = triangles.Get(x, y - 1) as GridTriangle; GridTriangle up = triangles.Get(x, y + 1) as GridTriangle; if (down != null && down.id == tile.id && down.subId == tile.subId) { down.height++; triangles.Set(x, y, down); isExpanded = true; } if (up != null && up.id == tile.id && up.subId == tile.subId) { if (isExpanded) { down.height += up.height; for (int i = y + 1; i <= y + up.height; i++) { triangles.Set(x, i, down); } } else { up.height++; up.bottomLeftY--; triangles.Set(x, y, up); isExpanded = true; } } if (isExpanded) { if (down != null) { int actualSize; Sprite sprite = info.GetSprite(out actualSize, down.subId, down.height); int relBottomY = down.bottomLeftY - currentRenderer.regionY * Grid.REGION_SIZE; if (relBottomY > Grid.REGION_SIZE / 2) { RenderUpTriangle(currentRenderer, relX, relBottomY, down.height, actualSize, sprite); } else { RenderDownTriangle(currentRenderer, relX, relBottomY, down.height, actualSize, sprite); } } else if (up != null) { int actualSize; Sprite sprite = info.GetSprite(out actualSize, up.subId, up.height); int relBottomY = up.bottomLeftY - currentRenderer.regionY * Grid.REGION_SIZE; if (relBottomY > Grid.REGION_SIZE / 2) { RenderUpTriangle(currentRenderer, relX, relBottomY, up.height, actualSize, sprite); } else { RenderDownTriangle(currentRenderer, relX, relBottomY, up.height, actualSize, sprite); } } } } else { GridTriangle left = triangles.Get(x - 1, y) as GridTriangle; GridTriangle right = triangles.Get(x + 1, y) as GridTriangle; if (left != null && left.id == tile.id && left.subId == tile.subId) { left.width++; triangles.Set(x, y, left); isExpanded = true; } if (right != null && right.id == tile.id && right.subId == tile.subId) { if (isExpanded) { left.width += right.width; for (int i = x + 1; i <= x + right.width; i++) { triangles.Set(i, y, left); } } else { right.width++; right.bottomLeftX--; triangles.Set(x, y, right); isExpanded = true; } } if (isExpanded) { if (left != null) { int actualSize; Sprite sprite = info.GetSprite(out actualSize, left.subId, left.width); int relBottomX = left.bottomLeftX - currentRenderer.regionX * Grid.REGION_SIZE; if (relBottomX > Grid.REGION_SIZE / 2) { RenderRightTriangle(currentRenderer, relBottomX, relY, left.width, actualSize, sprite); } else { RenderLeftTriangle(currentRenderer, relBottomX, relY, left.width, actualSize, sprite); } } else if (right != null) { int actualSize; Sprite sprite = info.GetSprite(out actualSize, right.subId, right.width); int relBottomX = right.bottomLeftX - currentRenderer.regionX * Grid.REGION_SIZE; if (relBottomX > Grid.REGION_SIZE / 2) { RenderRightTriangle(currentRenderer, relBottomX, relY, right.width, actualSize, sprite); } else { RenderLeftTriangle(currentRenderer, relBottomX, relY, right.width, actualSize, sprite); } } } } if (!isExpanded) { triangles.Set(x, y, GridTriangle.CreateTriangle(containerGO, grid, tile.id, tile.subId, info.isVertical, x, y, 1, 1)); currentRenderer.mesh.SetTile(relX, relY, info.GetSprite(tile.subId)); } }
void Clear(GridTriangle triangle, PositionRegionRenderer currentRenderer, int x, int y) { int relX = x - currentRenderer.regionX * Grid.REGION_SIZE; int relY = y - currentRenderer.regionY * Grid.REGION_SIZE; if (triangle != null) { TileInfo info = grid.atlas [triangle.id]; int actualSize; if (triangle.isVertical) { int bottomRelY = triangle.bottomLeftY - currentRenderer.regionY * Grid.REGION_SIZE; if (y == triangle.bottomLeftY) { if (triangle.height == 1) { DestroyImmediate(triangle.gameObject); } else { triangle.height -= 1; triangle.bottomLeftY += 1; Sprite sprite = info.GetSprite(out actualSize, triangle.subId, triangle.height); RenderUpTriangle(currentRenderer, relX, bottomRelY + 1, triangle.height, actualSize, sprite); } } else if (y == triangle.bottomLeftY + triangle.height - 1) { triangle.height -= 1; Sprite sprite = info.GetSprite(out actualSize, triangle.subId, triangle.height); RenderDownTriangle(currentRenderer, relX, bottomRelY, triangle.height, actualSize, sprite); } else { GridTriangle other = GridTriangle.CreateTriangle( containerGO, grid, triangle.id, triangle.subId, true, triangle.bottomLeftX, y + 1, 1, triangle.height - (y + 1 - triangle.bottomLeftY) ); triangle.height = y - triangle.bottomLeftY; Sprite sprite = info.GetSprite(out actualSize, triangle.subId, triangle.height); RenderDownTriangle(currentRenderer, relX, bottomRelY, triangle.height, actualSize, sprite); sprite = info.GetSprite(out actualSize, other.subId, other.height); bottomRelY = other.bottomLeftY - currentRenderer.regionY * Grid.REGION_SIZE; for (int i = 0; i < other.height; i++) { triangles.Set(other.bottomLeftX, other.bottomLeftY + i, other); } RenderUpTriangle(currentRenderer, relX, bottomRelY, other.height, actualSize, sprite); } } else { int bottomRelX = triangle.bottomLeftX - currentRenderer.regionX * Grid.REGION_SIZE; if (x == triangle.bottomLeftX) { if (triangle.width == 1) { DestroyImmediate(triangle.gameObject); } else { triangle.width -= 1; triangle.bottomLeftX += 1; Sprite sprite = info.GetSprite(out actualSize, triangle.subId, triangle.width); RenderRightTriangle(currentRenderer, bottomRelX + 1, relY, triangle.width, actualSize, sprite); } } else if (x == triangle.bottomLeftX + triangle.width - 1) { triangle.width -= 1; Sprite sprite = info.GetSprite(out actualSize, triangle.subId, triangle.width); RenderLeftTriangle(currentRenderer, bottomRelX, relY, triangle.width, actualSize, sprite); } else { GridTriangle other = GridTriangle.CreateTriangle( containerGO, grid, triangle.id, triangle.subId, false, x + 1, triangle.bottomLeftY, triangle.width - (x + 1 - triangle.bottomLeftX), 1 ); triangle.width = x - triangle.bottomLeftX; Sprite sprite = info.GetSprite(out actualSize, triangle.subId, triangle.width); RenderLeftTriangle(currentRenderer, bottomRelX, relY, triangle.width, actualSize, sprite); sprite = info.GetSprite(out actualSize, other.subId, other.width); bottomRelX = other.bottomLeftX - currentRenderer.regionX * Grid.REGION_SIZE; for (int i = 0; i < other.width; i++) { triangles.Set(other.bottomLeftX + i, other.bottomLeftY, other); } RenderRightTriangle(currentRenderer, bottomRelX, relY, other.width, actualSize, sprite); } } triangles.Set(x, y, null); } currentRenderer.mesh.Clear(relX, relY); }
public override void OnSet(int x, int y, Tile tile) { // clear previous ClearTile(x, y); TileInfo info = grid.atlas [tile.id]; // add new if (info.shape != TileShape.EMPTY) { GridColliderPart wrapper = null; // HORIZONTAL GROWTH if (info.shape != TileShape.LEFT_ONEWAY && info.shape != TileShape.RIGHT_ONEWAY) { bool expanded = false; GridColliderPart left = components.Get(x - 1, y) as GridColliderPart; if (left != null && left.Compatible(info) && !left.isVertical && !info.isVertical) { left.SetSize(left.width + 1, 1); wrapper = left; components.Set(x, y, left); expanded = true; } GridColliderPart right = components.Get(x + 1, y) as GridColliderPart; if (right != null && right.Compatible(info) && !right.isVertical && !info.isVertical) { if (!expanded) { right.bottomLeftX -= 1; right.SetSize(right.width + 1, 1); wrapper = right; components.Set(x, y, right); wrapper.ResetSizeAndPosition(grid); return; } else { left.SetSize(left.width + right.width, 1); for (int i = right.bottomLeftX; i < right.bottomLeftX + right.width; i++) { components.Set(i, y, left); } if (Application.isPlaying) { Destroy(right.gameObject); } else { DestroyImmediate(right.gameObject); } wrapper.ResetSizeAndPosition(grid); return; } } if (expanded) { wrapper.ResetSizeAndPosition(grid); return; } } // VERTICAL GROWTH if (info.shape != TileShape.FULL && info.shape != TileShape.UP_ONEWAY && info.shape != TileShape.DOWN_ONEWAY) { bool expanded = false; GridColliderPart down = components.Get(x, y - 1) as GridColliderPart; if (down != null && down.Compatible(info) && down.isVertical && info.isVertical) { down.SetSize(1, down.height + 1); wrapper = down; components.Set(x, y, down); expanded = true; } GridColliderPart up = components.Get(x, y + 1) as GridColliderPart; if (up != null && up.Compatible(info) && up.isVertical && info.isVertical) { if (!expanded) { up.bottomLeftY -= 1; up.SetSize(1, up.height + 1); wrapper = up; components.Set(x, y, up); wrapper.ResetSizeAndPosition(grid); return; } else { down.SetSize(1, down.height + up.height); for (int i = up.bottomLeftY; i < up.bottomLeftY + up.width; i++) { components.Set(i, y, down); } if (Application.isPlaying) { Destroy(up.gameObject); } else { DestroyImmediate(up.gameObject); } wrapper.ResetSizeAndPosition(grid); return; } } if (expanded) { wrapper.ResetSizeAndPosition(grid); return; } } // NO EXPANSE, CREATE NEW wrapper = GridColliderPart.CreateColliderPart(containerGO, grid, info, x, y, 1, 1); components.Set(x, y, wrapper); wrapper.ResetSizeAndPosition(grid); } }
public override void OnShowRegion(int regionX, int regionY) { int bx = regionX * Grid.REGION_SIZE; int by = regionY * Grid.REGION_SIZE; FiniteGrid region = grid.GetRegion(regionX, regionY); FiniteComponentGrid regionComponents = components.GetOrCreateRegion(regionX, regionY); for (int y = 0; y < Grid.REGION_SIZE; y++) { GridColliderPart currentWrapper = components.Get(bx - 1, y + by) as GridColliderPart; for (int x = 0; x < Grid.REGION_SIZE - 1; x++) { Tile tile = region.Get(x, y); if (tile != null) { TileInfo info = grid.atlas [tile.id]; if (currentWrapper != null && currentWrapper.Compatible(info) && !info.isVertical && !currentWrapper.isVertical) { currentWrapper.width++; } else { if (currentWrapper != null) { currentWrapper.ResetSizeAndPosition(grid); } if (info.shape != TileShape.EMPTY && !info.isVertical) { currentWrapper = GridColliderPart.CreateColliderPart(containerGO, grid, info, bx + x, by + y, 1, 1); } else { currentWrapper = null; } } regionComponents.Set(x, y, currentWrapper); } else { if (currentWrapper != null) { currentWrapper.ResetSizeAndPosition(grid); currentWrapper = null; } regionComponents.Set(x, y, null); } } if (currentWrapper != null) { currentWrapper.ResetSizeAndPosition(grid); } Tile edgeTile = region.Get(Grid.REGION_SIZE - 1, y); if (edgeTile != null) { OnSet(bx + Grid.REGION_SIZE - 1, by + y, edgeTile); } } for (int x = 0; x < Grid.REGION_SIZE; x++) { GridColliderPart currentWrapper = components.Get(bx + x, by - 1) as GridColliderPart; for (int y = 0; y < Grid.REGION_SIZE - 1; y++) { Tile tile = region.Get(x, y); if (tile != null) { TileInfo info = grid.atlas [tile.id]; if (currentWrapper != null && currentWrapper.Compatible(info) && info.isVertical && currentWrapper.isVertical) { currentWrapper.height++; regionComponents.Set(x, y, currentWrapper); } else { if (currentWrapper != null) { currentWrapper.ResetSizeAndPosition(grid); } if (info.shape != TileShape.EMPTY && info.isVertical) { currentWrapper = GridColliderPart.CreateColliderPart(containerGO, grid, info, bx + x, by + y, 1, 1); regionComponents.Set(x, y, currentWrapper); } else { currentWrapper = null; } } } else { if (currentWrapper != null) { currentWrapper.ResetSizeAndPosition(grid); currentWrapper = null; } } } if (currentWrapper != null) { currentWrapper.ResetSizeAndPosition(grid); } Tile edgeTile = region.Get(x, Grid.REGION_SIZE - 1); if (edgeTile != null && grid.atlas[edgeTile.id].isVertical) { OnSet(bx + x, by + Grid.REGION_SIZE - 1, edgeTile); } } }