public ColliderFactoryIsometric(float mapTileWidth, float mapTileHeight, SuperImportContext importContext) : base(importContext) { m_MapTileWidth = mapTileWidth; m_MapTileHeight = mapTileHeight; }
private void PlaceTileAsObject(GameObject goTilemap, SuperTile tile, int cx, int cy, TileIdMath tileId, Vector3Int pos3) { Assert.IsNotNull(goTilemap.GetComponentInParent <SuperMap>()); Assert.IsNotNull(goTilemap.GetComponentInParent <SuperLayer>()); var superMap = goTilemap.GetComponentInParent <SuperMap>(); var superLayer = goTilemap.GetComponentInParent <SuperLayer>(); var color = new Color(1, 1, 1, superLayer.CalculateOpacity()); string tileName = string.Format("tile ({0}, {1})", cx, cy); var goTRS = new GameObject(string.Format("{0} (TRS)", tileName)); goTilemap.AddChildWithUniqueName(goTRS); // Create a faux SuperObject component to add to our placed tile // We need this in case we have custom scripts that are looking for tile object via component { var tileObject = goTRS.AddComponent <SuperObject>(); tileObject.m_Id = m_ObjectIdCounter++; tileObject.m_TiledName = string.Format("AsObject_{0}", tileObject.m_Id); tileObject.m_X = pos3.x * superMap.m_TileWidth; tileObject.m_Y = -pos3.y * superMap.m_TileHeight; tileObject.m_Width = tile.m_Width; tileObject.m_Height = tile.m_Height; tileObject.m_TileId = (uint)tile.m_TileId; tileObject.m_Visible = true; // Does the tile have any properties? if (!tile.m_CustomProperties.IsEmpty()) { var component = tileObject.gameObject.AddComponent <SuperCustomProperties>(); component.m_Properties = new List <CustomProperty>(); component.m_Properties.CombineFromSource(tile.m_CustomProperties); } } Vector3 translate, rotate, scale; tile.GetTRS(tileId.FlipFlags, m_MapComponent.m_Orientation, out translate, out rotate, out scale); var cellPos = superMap.CellPositionToLocalPosition(pos3.x, pos3.y); translate.x += cellPos.x; translate.y += cellPos.y; if (m_MapComponent.m_Orientation == MapOrientation.Isometric || m_MapComponent.m_Orientation == MapOrientation.Staggered) { translate.x -= SuperImportContext.MakeScalar(m_MapComponent.m_TileWidth) * 0.5f; } else if (m_MapComponent.m_Orientation == MapOrientation.Hexagonal) { translate.x -= SuperImportContext.MakeScalar(m_MapComponent.m_TileWidth) * 0.5f; translate.y -= SuperImportContext.MakeScalar(m_MapComponent.m_TileHeight) * 0.5f; } // Add the game object for the tile goTRS.transform.localPosition = translate; goTRS.transform.localRotation = Quaternion.Euler(rotate); goTRS.transform.localScale = scale; // Add the sprite renderer component var renderer = goTRS.AddComponent <SpriteRenderer>(); renderer.sprite = tile.m_Sprite; renderer.color = color; AssignMaterial(renderer); AssignSpriteSorting(renderer); if (!tile.m_AnimationSprites.IsEmpty()) { var tileAnimator = goTRS.AddComponent <TileObjectAnimator>(); tileAnimator.m_AnimationFramerate = SuperImportContext.Settings.AnimationFramerate; tileAnimator.m_AnimationSprites = tile.m_AnimationSprites; } // Add any colliders that may be on the tile object tile.AddCollidersForTileObject(goTRS, SuperImportContext); }
private static void AddBoxCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { var box = go.AddComponent <BoxCollider2D>(); box.offset = importContext.MakePointPPU(collision.m_Size.x, -collision.m_Size.y) * 0.5f; box.size = importContext.MakeSize(collision.m_Size); var xpos = importContext.MakeScalar(collision.m_Position.x); var ypos = importContext.MakeScalar(collision.m_Position.y); go.transform.localPosition = new Vector3(xpos, ypos); go.transform.localEulerAngles = new Vector3(0, 0, importContext.MakeRotation(collision.m_Rotation)); go.AddComponent <SuperColliderComponent>(); }
private bool ProcessGridObject(XElement xMap) { // Add the grid to the map var goGrid = new GameObject("Grid"); goGrid.transform.SetParent(m_MapComponent.gameObject.transform); // The grid is added to the asset because without it we get prefab modifications for all collision geometry and tile matrices // Note: this is crashing Unity 2018.3. Unfortunately prefab instances will be fatter in those versions of Unity. :( #if UNITY_2019_1_OR_NEWER SuperImportContext.AddObjectToAsset("_grid", goGrid); #endif m_GridComponent = goGrid.AddComponent <Grid>(); // Grid cell size always has a z-value of 1 so that we can use custom axis sorting float sx = SuperImportContext.MakeScalar(m_MapComponent.m_TileWidth); float sy = SuperImportContext.MakeScalar(m_MapComponent.m_TileHeight); m_GridComponent.cellSize = new Vector3(sx, sy, 1); var localPosition = new Vector3(0, 0, 0); switch (m_MapComponent.m_Orientation) { #if UNITY_2018_3_OR_NEWER case MapOrientation.Isometric: m_GridComponent.cellLayout = GridLayout.CellLayout.Isometric; localPosition = new Vector3(0, -sy, 0); break; case MapOrientation.Staggered: m_GridComponent.cellLayout = GridLayout.CellLayout.Isometric; if (m_MapComponent.m_StaggerAxis == StaggerAxis.Y) { if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * 0.5f, -sy, 0); } else { localPosition = new Vector3(sx, -sy, 0); } } else if (m_MapComponent.m_StaggerAxis == StaggerAxis.X) { if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * 0.5f, -sy, 0); } else { localPosition = new Vector3(sx * 0.5f, -sy * 1.5f, 0); } } break; case MapOrientation.Hexagonal: if (m_MapComponent.m_StaggerAxis == StaggerAxis.Y) { // Pointy-top hex maps m_GridComponent.cellLayout = GridLayout.CellLayout.Hexagon; m_GridComponent.cellSwizzle = GridLayout.CellSwizzle.XYZ; if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * 0.5f, sy * -0.5f, 0); } else { localPosition = new Vector3(sx * 0.5f, sy * 0.25f, 0); } } else if (m_MapComponent.m_StaggerAxis == StaggerAxis.X) { // Flat-top hex maps. Reverse x and y on size. m_GridComponent.cellLayout = GridLayout.CellLayout.Hexagon; m_GridComponent.cellSwizzle = GridLayout.CellSwizzle.YXZ; m_GridComponent.cellSize = new Vector3(sy, sx, 1); if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * -0.25f, -sy, 0); } else { localPosition = new Vector3(sx * 0.5f, -sy, 0); } } break; #endif default: m_GridComponent.cellLayout = GridLayout.CellLayout.Rectangle; localPosition = new Vector3(0, -sy, 0); break; } m_GridComponent.transform.localPosition = localPosition; return(true); }
private static void AddEdgeCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { var edge = go.AddComponent <EdgeCollider2D>(); edge.points = importContext.MakePointsPPU(collision.Points); go.AddComponent <SuperColliderComponent>(); }
private void ProcessLayerData(GameObject goLayer, XElement xData) { Assert.IsNotNull(goLayer); Assert.IsNotNull(goLayer.GetComponent <SuperTileLayer>()); Assert.IsNotNull(xData); SuperTileLayer superComp = goLayer.GetComponent <SuperTileLayer>(); var chunk = new Chunk(); chunk.Encoding = xData.GetAttributeAs <DataEncoding>("encoding"); chunk.Compression = xData.GetAttributeAs <DataCompression>("compression"); bool tilesAsObjects = m_MapComponent.m_Orientation == MapOrientation.Isometric || m_TilesAsObjects; // Are we reading in data in smaller chunks (for infinite maps) or one big chunk (the full map) var xChunks = xData.Elements("chunk"); if (xChunks.Any()) { foreach (var xChunk in xChunks) { chunk.XmlChunk = xChunk; chunk.X = xChunk.GetAttributeAs <int>("x"); chunk.Y = xChunk.GetAttributeAs <int>("y"); chunk.Width = xChunk.GetAttributeAs <int>("width"); chunk.Height = xChunk.GetAttributeAs <int>("height"); // Each chunk is a separate game object on the super layer GameObject goChunk = new GameObject(string.Format("Chunk ({0},{1})", chunk.X, chunk.Y)); goLayer.AddChildWithUniqueName(goChunk); // Possition the chunk Vector3Int int3 = m_MapComponent.TilePositionToGridPosition(chunk.X, chunk.Y); Vector3 translate = SuperImportContext.MakePoint(int3.x, int3.y); translate.x *= m_MapComponent.m_TileWidth; translate.y *= m_MapComponent.m_TileHeight; goChunk.transform.localPosition = translate; // Create the tilemap for the layer if needed if (!tilesAsObjects) { var tilemap = goChunk.AddComponent <Tilemap>(); tilemap.tileAnchor = Vector3.zero; tilemap.animationFrameRate = SuperImportContext.Settings.AnimationFramerate; tilemap.color = new Color(1, 1, 1, superComp.CalculateOpacity()); // Create the renderer for the layer var renderer = goChunk.AddComponent <TilemapRenderer>(); renderer.sortOrder = MapRenderConverter.Tiled2Unity(m_MapComponent.m_RenderOrder); AssignSortingLayer(renderer, superComp.m_SortingLayerName, superComp.m_SortingOrder); } ProcessLayerDataChunk(goChunk, chunk); } } else { // Regular maps only have one chunk with the Tilemap and TileRenderer being on the layer object // Add the tilemap components if needed if (!tilesAsObjects) { var tilemap = goLayer.AddComponent <Tilemap>(); tilemap.tileAnchor = Vector3.zero; tilemap.animationFrameRate = SuperImportContext.Settings.AnimationFramerate; tilemap.color = new Color(1, 1, 1, superComp.CalculateOpacity()); // Create the renderer for the layer var renderer = goLayer.AddComponent <TilemapRenderer>(); renderer.sortOrder = MapRenderConverter.Tiled2Unity(m_MapComponent.m_RenderOrder); AssignSortingLayer(renderer, superComp.m_SortingLayerName, superComp.m_SortingOrder); } // For regular maps the 'chunk' is the same as the layer data chunk.XmlChunk = xData; chunk.X = 0; chunk.Y = 0; chunk.Width = m_MapComponent.m_Width; chunk.Height = m_MapComponent.m_Height; ProcessLayerDataChunk(goLayer, chunk); } }
public static void AddCollidersForTileObject(this SuperTile tile, GameObject goParent, SuperImportContext importContext) { Assert.IsNotNull(tile); Assert.IsNotNull(goParent); Assert.IsNotNull(importContext); if (!tile.m_CollisionObjects.IsNullOrEmpty()) { foreach (var collision in tile.m_CollisionObjects) { collision.AddCollider(tile, goParent, importContext); } } }
public static void AddCollider(this CollisionObject collision, SuperTile tile, GameObject goParent, SuperImportContext importContext) { var go = new GameObject(collision.m_ObjectName); if (collision.CollisionShapeType == CollisionShapeType.Polygon) { AddPolygonCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Polyline) { AddEdgeCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Ellipse) { AddEllipseCollider(go, collision, tile, importContext); } else if (collision.CollisionShapeType == CollisionShapeType.Rectangle) { AddBoxCollider(go, collision, tile, importContext); } // Additional settings on the collider that was just added var addedCollider = go.GetComponent <Collider2D>(); if (addedCollider != null) { addedCollider.isTrigger = importContext.GetIsTriggerOverridable(collision.m_IsTrigger); } goParent.AddChildWithUniqueName(go); }
private bool ProcessGridObject(XElement xMap) { // Add the grid to the map var goGrid = new GameObject("Grid"); goGrid.transform.SetParent(m_MapComponent.gameObject.transform); m_GridComponent = goGrid.AddComponent <Grid>(); // Grid cell size always has a z-value of 1 so that we can use custom axis sorting float sx = SuperImportContext.MakeScalar(m_MapComponent.m_TileWidth); float sy = SuperImportContext.MakeScalar(m_MapComponent.m_TileHeight); m_GridComponent.cellSize = new Vector3(sx, sy, 1); var localPosition = new Vector3(0, 0, 0); switch (m_MapComponent.m_Orientation) { #if UNITY_2018_3_OR_NEWER case MapOrientation.Isometric: m_GridComponent.cellLayout = GridLayout.CellLayout.Isometric; localPosition = new Vector3(0, -sy, 0); break; case MapOrientation.Staggered: m_GridComponent.cellLayout = GridLayout.CellLayout.Isometric; if (m_MapComponent.m_StaggerAxis == StaggerAxis.Y) { if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * 0.5f, -sy, 0); } else { localPosition = new Vector3(sx, -sy, 0); } } else if (m_MapComponent.m_StaggerAxis == StaggerAxis.X) { if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * 0.5f, -sy, 0); } else { localPosition = new Vector3(sx * 0.5f, -sy * 1.5f, 0); } } break; case MapOrientation.Hexagonal: if (m_MapComponent.m_StaggerAxis == StaggerAxis.Y) { // Pointy-top hex maps m_GridComponent.cellLayout = GridLayout.CellLayout.Hexagon; m_GridComponent.cellSwizzle = GridLayout.CellSwizzle.XYZ; if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * 0.5f, sy * -0.5f, 0); } else { localPosition = new Vector3(sx * 0.5f, sy * 0.25f, 0); } } else if (m_MapComponent.m_StaggerAxis == StaggerAxis.X) { // Flat-top hex maps. Reverse x and y on size. m_GridComponent.cellLayout = GridLayout.CellLayout.Hexagon; m_GridComponent.cellSwizzle = GridLayout.CellSwizzle.YXZ; m_GridComponent.cellSize = new Vector3(sy, sx, 1); if (m_MapComponent.m_StaggerIndex == StaggerIndex.Odd) { localPosition = new Vector3(sx * -0.25f, -sy, 0); } else { localPosition = new Vector3(sx * 0.5f, -sy, 0); } } break; #endif default: m_GridComponent.cellLayout = GridLayout.CellLayout.Rectangle; localPosition = new Vector3(0, -sy, 0); break; } m_GridComponent.transform.localPosition = localPosition; return(true); }
public ColliderFactoryOrthogonal(SuperImportContext importContext) : base(importContext) { }
// Creates a new object, attached to the parent, with a specialized layer component public static T AddSuperLayerGameObject <T>(this GameObject goParent, SuperLayerLoader loader, SuperImportContext importContext) where T : SuperLayer { GameObject goLayer = new GameObject(); // Read in the fields common across our Tiled layer types var layerComponent = loader.CreateLayer(goLayer) as T; Assert.IsNotNull(layerComponent); // Add the object to the parent goLayer.name = layerComponent.m_TiledName; goParent.AddChildWithUniqueName(goLayer); return(layerComponent); }
// Group convex polygons into a composite collider public static void AddCompositePolygonCollider(GameObject go, List <Vector2[]> convexPolygons, SuperImportContext context) { // If there is only one convex polygon then don't use a composite if (convexPolygons.Count == 1) { var polyCollider = go.AddComponent <PolygonCollider2D>(); polyCollider.SetPath(0, convexPolygons[0]); polyCollider.gameObject.AddComponent <SuperColliderComponent>(); } else { // Rigid body is needed for composite collider var rigid = go.AddComponent <Rigidbody2D>(); rigid.bodyType = RigidbodyType2D.Static; rigid.simulated = true; // Colliders will be grouped by the composite // This way we have convex polygon paths (in the children) if needed // And we can have complex polygons represented by one object var composite = go.AddComponent <CompositeCollider2D>(); composite.geometryType = context.Settings.CollisionGeometryType; composite.generationType = CompositeCollider2D.GenerationType.Manual; // Add polygon colliders foreach (var path in convexPolygons) { var goPolygon = new GameObject("ConvexPolygon"); go.AddChildWithUniqueName(goPolygon); var polyCollider = goPolygon.AddComponent <PolygonCollider2D>(); polyCollider.usedByComposite = true; polyCollider.SetPath(0, path); polyCollider.gameObject.AddComponent <SuperColliderComponent>(); } composite.ST2UGenerateGeometry(); } }
public CollisionBuilder(GameObject goTilemap, Dictionary <uint, TilePolygonCollection> tilePolygonDatabase, SuperImportContext importContext) { m_TilemapGameObject = goTilemap; m_TilePolygonDatabase = tilePolygonDatabase; m_ImportContext = importContext; }
public ScopedIsTriggerOverride(SuperImportContext superContext) { m_SuperContext = superContext; }
// Creates a new object, attached to the parent, with a specialized layer component public static T AddSuperLayerGameObject <T>(this GameObject goParent, SuperLayerLoader loader, SuperImportContext importContext) where T : SuperLayer { GameObject goLayer = new GameObject(); // Read in the fields common across our Tiled layer types var layerComponent = loader.CreateLayer(goLayer) as T; Assert.IsNotNull(layerComponent); // Add the object to the parent goLayer.name = layerComponent.m_TiledName; goParent.AddChildWithUniqueName(goLayer); // Position the layer based on the x, y offsets and pixels per unit goLayer.transform.localPosition = importContext.MakePoint(layerComponent.m_OffsetX, layerComponent.m_OffsetY); return(layerComponent); }
public ScopedLayerIgnoreMode(SuperImportContext superContext, LayerIgnoreMode newIgnoreMode) { m_SuperContext = superContext; m_RestoreIgnoreMode = m_SuperContext.LayerIgnoreMode; m_SuperContext.LayerIgnoreMode = newIgnoreMode; }
public ColliderFactory(SuperImportContext importContext) { ImportContext = importContext; }
private static void AddPolygonCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { // Note that polygons may need to be decomposed into convex parts var points = importContext.MakePointsPPU(collision.Points); // Triangulate the polygon points var triangulator = new Triangulator(); var triangles = triangulator.TriangulatePolygon(points); // Gather triangles into a collection of convex polygons var composition = new ComposeConvexPolygons(); var convexPolygons = composition.Compose(triangles); PolygonUtils.AddCompositePolygonCollider(go, convexPolygons, importContext); }
private static void AddPointCollider(GameObject go, CollisionObject collision, SuperImportContext importContext) { var xpos = importContext.MakeScalar(collision.m_Position.x); var ypos = importContext.MakeScalar(collision.m_Position.y); go.transform.localPosition = new Vector3(xpos, ypos); go.transform.localEulerAngles = new Vector3(0, 0, importContext.MakeRotation(collision.m_Rotation)); go.AddComponent <SuperColliderComponent>(); }
private static void AddEllipseCollider(GameObject go, CollisionObject collision, SuperTile tile, SuperImportContext importContext) { // Add a circle collider if width == height. Otherwise, we have to use am approximate polygon representation. if (collision.m_Size.x == collision.m_Size.y) { var cirlce = go.AddComponent <CircleCollider2D>(); cirlce.offset = importContext.MakePointPPU(collision.m_Size.x, -collision.m_Size.y) * 0.5f; cirlce.radius = importContext.MakeScalar(collision.m_Size.x) * 0.5f; var xpos = importContext.MakeScalar(collision.m_Position.x); var ypos = importContext.MakeScalar(collision.m_Position.y); go.transform.localPosition = new Vector3(xpos, ypos); go.transform.localEulerAngles = new Vector3(0, 0, importContext.MakeRotation(collision.m_Rotation)); go.AddComponent <SuperColliderComponent>(); } else { AddPolygonCollider(go, collision, tile, importContext); } }
public static int AddPropertiesFromType(this List <CustomProperty> list, string typeName, SuperImportContext importContext) { if (list == null) { return(0); } if (string.IsNullOrEmpty(typeName)) { return(0); } CustomObjectType objectType; if (importContext.Settings.CustomObjectTypes.TryGetCustomObjectType(typeName, out objectType)) { return(CombineFromSource(list, objectType.m_CustomProperties)); } return(0); }