📜 ⬆️ ⬇️

Tiled2Unity: export from Tiled Map Editor to Unity

A lot of publications on resources for game developers are devoted to creating a simple 2D platformer. Unity is often used as an engine, and Tiled Map Editor is used for creating maps. The interaction of these two environments is carried out using the free utility Tiled2Unity, which creates prefabs in Unity from TME files.

How it works, we will tell on the example of the development of our platform “X-Drums”.

We will move according to the following scheme:
')
  1. Setting export Tiled2Unity
  2. Configuring Collisions in Tiled Map Editor
  3. Configure the settings that Tiled2Unity supports
  4. Setting custom parameters in Tiled Map Editor


1. Export Setting


So, we have a project in Unity and there is a map created in the Tiled Map Editor. Run Unity and import the Tiled2Unity.unitypackage .



In the Tiled Map Editor we call the command editing window:



Add a new command in which the path to the executable file Tiled2Unity.exe is registered. Instead of% mapfile Tiled automatically substitute the path to the map file. The final argument of this command is the path to the Tiled2Unity folder, which should have appeared in the project after import.



Run the command and in the window that appears, press the big button.



As a result of the export, we get the card prefab, which is located in the Tiled2Unity folder. Place this prefab on stage in Unity. Now, when working with the map in TME and exporting it, the prefab and the object on the scene will change in accordance with the changes in TME.



So we set up exporting a map from Tiled to Unity and created a gaming environment.

Now let's do the setting of objects on our map.

2. Collision Editor


First of all, we define the elements of the playing space, which will be obstacles for the hero. These are the floor, walls, soffits on the ceiling, as well as drums, protruding platforms on which the hero will jump.

Run the collision editor in Tiled:



Select the tile we need, for example, a part of the drum, and edit the polygons:



Similarly, we edit other tiles we need (floor, walls, etc.). As a result, when exporting, Tiled2Unity will automatically create PolygonCollider2D colliders, which will act as obstacles for the hero.





However, other game objects with which the hero can interact are more complex. The behavior of the plates, fans, notes and other elements is controlled by using components and scripts. To export such objects, you need to specify additional parameters in Tiled and then process them in Unity.

3. Parameters that Tiled2Unity supports


However, there is a list of parameters that we can use in Tiled without configuring them in Unity, since Tiled2Unity has already done this for us. Among them:
unity: layer
unity: sortingLayerName
unity: tag
unity: sortingOrder
unity: isTrigger
unity: ignore
The (physics) layer name in Unity
The Name of the Sorting Layer in Unity
The Name of the Tag in Unity
The `sorting in layer` value in Unity
Whether collider is a trigger or not
Ignore layer (or parts of it) during import (value = [false | true | collision | visual])

Let us set the parameters we need for drumsticks, on which the hero will jump:



When exporting to Unity, we get the following result:



The layer is set to the OneWayPlatform parameter, it is used for objects that are permeable to the bottom.



4. User parameters in Tiled


Processing of other parameters, let's call them “user-defined”, and exporting objects with such parameters, we will configure in Unity. You can set them in Tiled for both layers (objects) and objects. In different cases, the first or second option may be convenient. Consider how to implement this.

4.1. User parameters for layers (objects)

Set user parameters for the layer. We use this option for objects of the same type. In our game such are cymbals and sheet music. Their peculiarity is that they interact equally with the hero and do not need to distinguish them from each other.

Create a layer of objects in Tiled and place our plates on it. Then, set the AddObject parameter for the entire layer.



The field of its parameters for each dish remains empty.



Now we move to Unity, where we created a prefab for the plates and tied to it a script that determines their behavior when the hero jumps - they fall and return to their original position.

Let's write a code that, when importing plates for each object from Tiled, will create an instance of our prefab. To do this, create a CustomTiledImporterForHiHats script with a class that inherits the Tiled2Unity.ICustomTiledImporter interface and the [Tiled2Unity.CustomTiledImporter] attribute.

This Tiled2Unity script will call for each layer and object imported from Tiled. And, respectively, will be processed those layers or objects that have among parameters the AddObject parameter with the value “Hi-hat”.

using System.Collections.Generic; using UnityEditor; using UnityEngine; [Tiled2Unity.CustomTiledImporter] class CustomTiledImporterForHiHats : Tiled2Unity.ICustomTiledImporter { public void HandleCustomProperties(GameObject gameObject, IDictionary<string, string> props) { if (!props.ContainsKey("AddObject")) return; if (props["AddObject"] == "Hi-hat") { //   string prefabPath = "Assets/8 - Prefabs/Hi-hat.prefab"; Object obj = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); if (obj == null) return; //  ,     Tiled, //    //      List<GameObject> childrenToDestroy = new List<GameObject>(); //     foreach (Transform child in gameObject.transform) { if (child.name == "TileObject") { //     childrenToDestroy.Add(child.gameObject); //  ,      GameObject objInstance = (GameObject)GameObject.Instantiate(obj); objInstance.name = obj.name; objInstance.transform.parent = gameObject.transform; objInstance.transform.position = child.transform.position; } } //    childrenToDestroy.ForEach(child => GameObject.DestroyImmediate(child)); } } public void CustomizePrefab(GameObject prefab) { } } 

The script is ready and we can export plates.



And so the hero interacts with them.



The export of notes is set up just like the export of plates. The only difference is that the game has several types of notes with different values ​​depending on the color. Therefore, for each type of note with its nominal value, we created a prefab in Unity and a layer of objects in Tiled, specifying the note type in the AddObject parameter. The import script that creates prefab instances is identical to the cymbal script.

4.2. User parameters for objects

Now we will consider how to export objects of the same type, in which user parameters are not set to the layer, but to the object itself. These objects include our fans, cupids, moving platforms, etc. Despite their uniformity, they have their own individual properties: speed, direction, etc.

For example, fans differ in color, they move at different speeds at a given distance. They can stop to blink, and when they meet with the hero, they give a choice of certain emotions. We set these parameters in Tiled for each object. “Their parameters” for the layer, respectively, remain empty.



In Unity, for fans, prefabs are created, to which GirlController script is attached, defining their behavior and reaction to the hero. The import will be similar to the import of plates, but simply creating copies of the prefab in this case will not be enough. We need to access the GirlController script and set the properties that were set in Tiled individually for each fan.

 using System.Collections.Generic; using UnityEditor; using UnityEngine; [Tiled2Unity.CustomTiledImporter] class CustomTiledImporterForGirls : Tiled2Unity.ICustomTiledImporter { public void HandleCustomProperties(GameObject gameObject, IDictionary<string, string> props) { if (!props.ContainsKey("GirlColor")) return; //        Tiled  string prefabPath = "Assets/8 - Prefabs/Girls/Girl_" + props["GirlColor"] + ".prefab"; Object obj = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); //  ,      GameObject objInstance = (GameObject)Object.Instantiate(obj); objInstance.name = obj.name; objInstance.transform.parent = gameObject.transform.parent; objInstance.transform.position = gameObject.transform.position; objInstance.transform.localScale = gameObject.transform.localScale; objInstance.transform.eulerAngles = gameObject.transform.eulerAngles; //  ,     //   Tiled     var girlController = objInstance.GetComponent<GirlController>(); if (props.ContainsKey("OffsetRight")) float.TryParse(props["OffsetRight"], out girlController.OffsetMax); if (props.ContainsKey("OffsetLeft")) float.TryParse(props["OffsetLeft"], out girlController.OffsetMin); if (props.ContainsKey("Velocity")) float.TryParse(props["Velocity"], out girlController.Velocity); if (props.ContainsKey("Stop")) float.TryParse(props["Stop"], out girlController.StopCount); if (props.ContainsKey("Fatal")) bool.TryParse(props["Fatal"], out girlController.Fatal); if (props.ContainsKey("HeartType")) { string heartPrefabPath = "Assets/8 - Prefabs/Girls/" + props["HeartType"] + ".prefab"; Object heartObj = AssetDatabase.LoadAssetAtPath(heartPrefabPath, typeof(GameObject)); girlController.heartPrefab = heartObj; } //    Object.DestroyImmediate(gameObject); } public void CustomizePrefab(GameObject prefab) { } } 

We export to Unity and see that the parameters specified in Tiled were set to the GirlController script variables:





We repeat the described scheme for objects from other groups, and when exporting to Unity we get customized prefabs for most of the game’s components.

The described approach was used by us to create our platform. Working in conjunction with the Tiled Map Editor and Unity, it was in this game that accelerated the process of its creation, allowing the TME level designer and the Unity programmer to work simultaneously, without interfering with each other. In projects like ours, the Tiled2Unity utility can be incredibly useful, and, based on the article, those who wish can apply any of the options in their game development.

Source: https://habr.com/ru/post/328700/


All Articles