Last active
August 29, 2015 14:22
-
-
Save anzfactory/0d4afb048b04f2bb85f8 to your computer and use it in GitHub Desktop.
[Unity]TiledMapEditorで作ったファイルを読み込んでタイルを敷き詰めるスクリプト群 ( http://anz-note.tumblr.com/post/120453126046/unity-tiledmap )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************* | |
2015-05-31 TiledMapデータ | |
(.xmlの要素に従って配置) | |
*********************************/ | |
using System.Collections.Generic; | |
using System.Xml.Serialization; | |
using UniLinq; | |
[XmlRoot("map")] | |
public class TiledMap | |
{ | |
public class TileSet | |
{ | |
[XmlAttribute("firstgid")] | |
public int FirstGID; | |
[XmlAttribute("name")] | |
public string Name; | |
[XmlAttribute("tilewidth")] | |
public int TileWidth; | |
[XmlAttribute("tileheight")] | |
public int TileHeight; | |
[XmlElement("image")] | |
public Image SourceImage; | |
[XmlElement("tile")] | |
public List<Tile> Tiles; | |
} | |
public class Properties | |
{ | |
[XmlElement("property")] | |
public List<Property> All; | |
public Property Find(string name) | |
{ | |
if (this.All == null) { | |
return null; | |
} | |
foreach (var p in this.All) { | |
if (p.Name.Equals(name)) { | |
return p; | |
} | |
} | |
return null; | |
} | |
public override string ToString() | |
{ | |
if (this.All == null || this.All.Count == 0) { | |
return "no properties..."; | |
} | |
return string.Join("\n", this.All.Select(p => { | |
return p.ToString(); | |
}).ToArray()); | |
} | |
} | |
public class Property | |
{ | |
[XmlAttribute("name")] | |
public string Name; | |
[XmlAttribute("value")] | |
public string Value; | |
public override string ToString() | |
{ | |
return string.Format("key:{0} value:{1}", this.Name, this.Value); | |
} | |
} | |
public class Layer | |
{ | |
[XmlAttribute("name")] | |
public string Name; | |
[XmlAttribute("width")] | |
public int Width; | |
[XmlAttribute("height")] | |
public int Height; | |
[XmlElement("data")] | |
public Data TileData; | |
} | |
public class Image | |
{ | |
[XmlAttribute("source")] | |
public string Source; | |
[XmlAttribute("width")] | |
public int Width; | |
[XmlAttribute("height")] | |
public int Height; | |
public string SourceName | |
{ | |
get { | |
return this.Source.Substring(0, Source.LastIndexOf(".")); | |
} | |
} | |
} | |
public class Data | |
{ | |
[XmlAttribute("encoding")] | |
public string Encoding; | |
[XmlElement("tile")] | |
public List<Tile> Tiles; | |
} | |
public class Tile | |
{ | |
[XmlAttribute("id")] | |
public int ID; | |
[XmlAttribute("gid")] | |
public int GID; | |
[XmlElement("properties")] | |
public Properties Properties; | |
} | |
public class ObjectGroup | |
{ | |
[XmlElement("object")] | |
public List<Object> Objects; | |
} | |
public class Object | |
{ | |
[XmlAttribute("id")] | |
public int ID; | |
[XmlAttribute("name")] | |
public string Name; | |
[XmlAttribute("type")] | |
public string Type; | |
[XmlAttribute("x")] | |
public int X; | |
[XmlAttribute("y")] | |
public int Y; | |
[XmlAttribute("width")] | |
public int Width; | |
[XmlAttribute("height")] | |
public int Height; | |
[XmlElement("properties")] | |
public Properties Properties; | |
} | |
[XmlAttribute("version")] | |
public string Version; | |
[XmlAttribute("orientation")] | |
public string Orientation; | |
[XmlAttribute("width")] | |
public int Width; // タイル数 | |
[XmlAttribute("height")] | |
public int Height; // タイル数 | |
[XmlAttribute("tilewidth")] | |
public int TileWidth; // 1タイルの横幅 | |
[XmlAttribute("tileheight")] | |
public int TileHeight; // 1タイルの縦幅 | |
[XmlElement("tileset")] | |
public List<TileSet> TileSets; | |
[XmlElement("layer")] | |
public List<Layer> Layers; | |
[XmlElement("objectgroup")] | |
public List<ObjectGroup> ObjectGroups; | |
public class TiledData | |
{ | |
public int Number; | |
public int ID; // レイヤー内での unique | |
public int GID; // 全レイヤー内での unique | |
public int X; | |
public int Y; | |
public List<Property> Properties; | |
public override string ToString() | |
{ | |
return string.Format("tile[{0}] ID:{1} GID:{2}, x-y:{3}-{4}", this.Number, this.ID, this.GID, this.X, this.Y); | |
} | |
} | |
private Dictionary<int, List<Property>> allProperty; | |
public List<TiledData> GetLayerData(string name) | |
{ | |
Layer targetLayer = this.GetLayer(name); | |
if (targetLayer == null) { | |
return null; | |
} | |
return this.GetLayerData(targetLayer); | |
} | |
public List<TiledData> GetLayerData(Layer targetLayer) | |
{ | |
List<Tile> tiles = targetLayer.TileData.Tiles; | |
List<TiledData> grid = new List<TiledData>(this.Width * this.Height); | |
TiledData data = null; | |
var allproperty = this.getProperties(); // マップに設定されているプロパティを全取得 | |
for(int y = 0; y < targetLayer.Height; y++) { | |
for(int x = 0; x < targetLayer.Width; x++) { | |
int tileNo = this.GetTileNo(x, y); | |
data = new TiledData(); | |
data.GID = tiles[tileNo].GID; | |
data.ID = this.convertToIDFromGID(data.GID); | |
data.X = x; | |
data.Y = y; | |
if (allproperty == null) { | |
data.Properties = null; | |
} else { | |
data.Properties = allproperty.ContainsKey(data.ID) ? allproperty[data.ID] : null; | |
} | |
grid.Add( data ); | |
} | |
} | |
return grid; | |
} | |
public Layer GetLayer(string name) | |
{ | |
foreach(var l in this.Layers){ | |
if(l.Name == name){ | |
return l; | |
} | |
} | |
return null; | |
} | |
private Dictionary<int, List<Property>> getProperties() | |
{ | |
// すでに一度ロードしていたらそれを返す | |
if (this.allProperty != null) { | |
return this.allProperty; | |
} | |
// MARK 複数タイルセットを考慮するならもう一手間 | |
TileSet currentTiseSet = this.TileSets[0]; | |
// マップによってはプロパティ設定が無いかもなので | |
if (currentTiseSet.Tiles == null || currentTiseSet.Tiles.Count == 0) { | |
return null; | |
} | |
this.allProperty = new Dictionary<int, List<Property>>(); | |
foreach (Tile t in currentTiseSet.Tiles) { | |
// ここの id から gid を作って設定しておく | |
this.allProperty[t.ID] = t.Properties.All; | |
} | |
return this.allProperty; | |
} | |
public int GetTileNo(int x, int y) | |
{ | |
return x + (y * this.Width); | |
} | |
private int convertToGIDFromID(int id) | |
{ | |
// MARK 複数のtilesetに対応するなら firstgid をちゃんと見て考慮する必要がある | |
return id + 1; | |
} | |
private int convertToIDFromGID(int gid) | |
{ | |
// MARK 複数のtilesetに対応するなら firstgid をちゃんと見て考慮する必要がある | |
return gid - 1; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************* | |
2015-05-30 | |
*********************************/ | |
using UnityEngine; | |
using System.Collections.Generic; | |
using UniLinq; | |
public class TiledMapCreator : MonoBehaviour | |
{ | |
public TextAsset TMX; | |
public Material TiledDefaultMaterial = null; | |
public string DirPath; | |
private TiledMap tiledMap = null; | |
private TiledMap.TileSet currentTileSet = null; | |
private List<Sprite> sliceTileSet = null; | |
private void Start() | |
{ | |
// 読み込んでパース | |
this.tiledMap = XMLParser.LoadFromXml<TiledMap>(this.TMX); | |
// 敷き詰め | |
this.CreateTiledMap(); | |
} | |
private void CreateTiledMap() | |
{ | |
this.currentTileSet = this.tiledMap.TileSets[0]; // 複数はとりあえず想定しない | |
// タイルセット画像をスライスしていく | |
this.SliceTilseSet(); | |
if (this.sliceTileSet == null || this.sliceTileSet.Count == 0) { | |
return; | |
} | |
// 敷き詰める | |
foreach (var layer in this.tiledMap.Layers) { | |
this.Tiled(layer); | |
} | |
// オブジェクト配置 | |
this.SetUpObjects(); | |
// カメラさんにプレイヤーを中央にして移すように移動してもらう | |
Camera.main.SendMessage("SetupPlayer"); | |
} | |
private void SliceTilseSet() | |
{ | |
string path = this.currentTileSet.SourceImage.SourceName; | |
Sprite textureMap = Resources.Load<Sprite>(this.DirPath + path); | |
if (textureMap == null) { | |
Debug.LogError("can not find tileset image..." + path); | |
return; | |
} | |
this.sliceTileSet = new List<Sprite>(this.tiledMap.Width * this.tiledMap.Height); | |
// スライスしていく | |
int width = this.currentTileSet.SourceImage.Width / this.currentTileSet.TileWidth; | |
int height = this.currentTileSet.SourceImage.Height / this.currentTileSet.TileHeight; | |
Vector2 pivot = new Vector2(0.5f, 0.5f); | |
int counter = 0; | |
for (int y = 0; y < height; y++) { | |
for (int x = 0; x < width; x++) { | |
// 範囲ぎめ | |
Rect rect = new Rect ( | |
x * this.tiledMap.TileWidth, | |
textureMap.texture.height - (y + 1) * this.tiledMap.TileHeight, | |
this.tiledMap.TileWidth, | |
this.tiledMap.TileHeight | |
); | |
// スライス | |
Sprite tile = Sprite.Create(textureMap.texture, rect, pivot, this.tiledMap.TileWidth); | |
// 格納 | |
this.sliceTileSet.Add(tile); | |
counter++; | |
} | |
} | |
} | |
private void Tiled(TiledMap.Layer layer) | |
{ | |
GameObject goLayer = new GameObject(layer.Name); | |
int layerIndex = LayerMask.NameToLayer(layer.Name); | |
if (layerIndex >= 0) { | |
goLayer.layer = layerIndex; | |
} | |
goLayer.transform.parent = this.gameObject.transform; | |
List<TiledMap.TiledData> tiles = this.tiledMap.GetLayerData(layer); | |
foreach (var tiledData in tiles) { | |
if (tiledData.GID == 0) { | |
// ブランクタイル | |
continue; | |
} | |
// タイルスプライトを作って設置 | |
GameObject tile = this.CreateTileSprite(tiledData, layer.Name); | |
tile.transform.position = new Vector3(tiledData.X, tiledData.Y * -1, 0); | |
tile.transform.parent = goLayer.transform; | |
tile.layer = goLayer.layer; | |
} | |
} | |
private GameObject CreateTileSprite(TiledMap.TiledData tiledData, string layerName) | |
{ | |
GameObject tile = new GameObject("tile_" + tiledData.GID); | |
SpriteRenderer tileRender = tile.AddComponent(typeof(SpriteRenderer)) as SpriteRenderer; | |
tileRender.sprite = this.sliceTileSet[tiledData.ID]; | |
tileRender.sortingLayerName = layerName; | |
tileRender.material = this.TiledDefaultMaterial; | |
// Collision設定 | |
this.SetCollision(tiledData, tile); | |
return tile; | |
} | |
private void SetCollision(TiledMap.TiledData tiledData, GameObject tile) | |
{ | |
if (tiledData.Properties == null || tiledData.Properties.Count == 0) { | |
return; | |
} | |
bool hasCollision = tiledData.Properties.Where(t => { | |
return t.Name.Equals("IsCollision") && t.Value.Equals("1"); | |
}).Any(); | |
if (hasCollision) { | |
var boxCollider2d = tile.AddComponent<BoxCollider2D>(); | |
boxCollider2d.size = new Vector2(0.9f, 0.9f); // ちょい小さくする | |
} | |
} | |
private void SetUpObjects() | |
{ | |
if (this.tiledMap.ObjectGroups == null || this.tiledMap.ObjectGroups.Count == 0) { | |
Debug.Log("not find objects..."); | |
return; | |
} | |
foreach (var objGroup in this.tiledMap.ObjectGroups) { | |
foreach (var obj in objGroup.Objects) { | |
var p = obj.Properties.Find("Path"); | |
string path = ""; | |
if (p != null) { | |
path = p.Value; | |
} | |
// TypeをPrefabの名前として扱う | |
GameObject go = Instantiate( | |
Resources.Load(path + obj.Type), | |
new Vector3(obj.X / obj.Width, obj.Y / obj.Height * -1, 0f), | |
this.gameObject.transform.rotation | |
) as GameObject; | |
if (obj.Properties == null) { | |
continue; | |
} | |
// レイヤーが指定されていればセット | |
p = obj.Properties.Find("Layer"); | |
if (p != null) { | |
go.layer = LayerMask.NameToLayer(p.Value); | |
} | |
// Sorting Layerが指定されていればセット | |
p = obj.Properties.Find("Sort"); | |
if (p != null) { | |
go.GetComponent<SpriteRenderer>().sortingLayerName = p.Value; | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************* | |
2015-05-31 XMLパーサー | |
*********************************/ | |
using UnityEngine; | |
using System.Xml.Serialization; | |
public class XMLParser | |
{ | |
public static T LoadFromXml<T> (TextAsset xml) | |
where T : class | |
{ | |
if (xml == null) { | |
Debug.LogError("Can not file xml file!! .... "); | |
return null; | |
} | |
var ser = new XmlSerializer (typeof(T)); | |
var stringReader = new System.IO.StringReader(xml.text); | |
var obj = ser.Deserialize(stringReader); | |
var retClass = (T)obj; | |
return retClass; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment