Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Tilemaps;
- public class ImageToLevel : MonoBehaviour
- {
- public Texture2D analyzeImage;
- public bool advancedMode;
- public Vector2Int tileSize = new Vector2Int(16, 16);
- public Tilemap copyMap;
- public CompareTileset tileset;
- //Parallel arrays
- public Sprite[] compareSprites;
- public TileBase[] compareTiles;
- [Range(0f, 100f)]
- public float precision = 99.9f;
- public bool autoClean = true;
- public TileBase[] cleanTiles;
- public int AnalyzeImage()
- {
- if (tileset != null)
- {
- compareSprites = tileset.compareSprites;
- compareTiles = tileset.tiles;
- cleanTiles = tileset.tilesForRemoval;
- }
- //Figure out how many tiles are on the map, assume the image is formatted properly
- int validTiles = 0;
- List<Vector3Int> positions = new List<Vector3Int>();
- List<TileBase> tiles = new List<TileBase>();
- List<Matrix4x4> rotations = new List<Matrix4x4>();
- for (int y = 0; y < analyzeImage.height / tileSize.y; y++)
- {
- for (int x = 0; x < analyzeImage.width / tileSize.x; x++)
- {
- TileAnalyzeData data = AnalyzeTile(x, y);
- if (data != null)
- {
- positions.Add(new Vector3Int(x, y, 0));
- tiles.Add(data.tile);
- rotations.Add(data.matrix);
- //copyMap.SetTile(new Vector3Int(x, y, 0), data.tile);
- //copyMap.SetTransformMatrix(new Vector3Int(x, y, 0), data.matrix);
- validTiles++;
- }
- }
- }
- copyMap.SetTiles(positions.ToArray(), tiles.ToArray());
- for (int i = 0; i < rotations.Count; i++)
- copyMap.SetTransformMatrix(positions[i], rotations[i]);
- return validTiles;
- }
- private TileAnalyzeData AnalyzeTile(int xTile, int yTile)
- {
- //Debug.Log("Analyzing tile " + new Vector2Int(xTile, yTile));
- //TODO: Rotate tile for checking
- for (int i = 0; i < compareTiles.Length; i++)
- {
- bool valid = true;
- //Normal
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + x, (int)compareSprites[i].rect.y + y);
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 0f), Vector3.one);
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Rotated left
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + y, (int)compareSprites[i].rect.y + (tileSize.x - 1 - x));
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 90f), Vector3.one);
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Rotated around
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + (tileSize.x - 1 - x), (int)compareSprites[i].rect.y + (tileSize.y - 1 - y));
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 180f), Vector3.one);
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Rotated right
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + (tileSize.x - 1 - x), (int)compareSprites[i].rect.y + x);
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 270f), Vector3.one);
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Flipped
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + (tileSize.x - 1 - x), (int)compareSprites[i].rect.y + y);
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 0f), new Vector3(-1, 1, 1));
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Flipped, Rotated left
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + y, (int)compareSprites[i].rect.y + (tileSize.x - 1 - x));
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 270f), new Vector3(-1, 1, 1));
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Flipped, Rotated around
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + x, (int)compareSprites[i].rect.y + (tileSize.y - 1 - y));
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 180f), new Vector3(-1, 1, 1));
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- //Flipped, Rotated right
- valid = true;
- for (int y = 0; y < tileSize.y; y++)
- {
- if (valid)
- for (int x = 0; x < tileSize.x; x++)
- {
- Color imageColor = analyzeImage.GetPixel(xTile * tileSize.x + x, yTile * tileSize.y + y);
- Texture2D texture = compareSprites[i].texture;
- Vector2Int textureLocation = new Vector2Int((int)compareSprites[i].rect.x + (tileSize.y - 1 - y), (int)compareSprites[i].rect.y + x);
- Color tileColor = texture.GetPixel(textureLocation.x, textureLocation.y);
- if (!CompareColor(imageColor, tileColor))
- {
- valid = false;
- break;
- }
- }
- }
- if (valid)
- {
- Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 90f), new Vector3(-1, 1, 1));
- return new TileAnalyzeData(compareTiles[i], matrix);
- }
- }
- return null;
- }
- //TODO: Ignore alpha in calculations? Include alpha as ignoring?
- private bool CompareColor(Color color1, Color color2, bool includeAlpha = false)
- {
- if (AlmostEqualRelative(color1.r, color2.r) &&
- AlmostEqualRelative(color1.g, color2.g) &&
- AlmostEqualRelative(color1.b, color2.b) &&
- (includeAlpha ? AlmostEqualRelative(color1.a, color2.a) : true))
- return true;
- return false;
- }
- bool AlmostEqualRelative(float A, float B)
- {
- float epsilon = (100f - precision) / 100f;
- // Calculate the difference.
- float diff = Mathf.Abs(A - B);
- A = Mathf.Abs(A);
- B = Mathf.Abs(B);
- // Find the largest
- float largest = (B > A) ? B : A;
- if (diff <= largest * epsilon)
- return true;
- return false;
- }
- /*public Texture2D singleTexture;
- public Sprite singleSprite;
- public void AnalyzeSprite()
- {
- bool valid = singleTexture.width == (int)singleSprite.rect.width && singleTexture.height == (int)singleSprite.rect.height;
- for (int y = 0; y < singleTexture.height; y++)
- {
- if (valid)
- for (int x = 0; x < singleTexture.width; x++)
- {
- Color imageColor = singleTexture.GetPixel(x, y);
- Color spriteColor = singleSprite.texture.GetPixel((int)singleSprite.rect.x + x, (int)singleSprite.rect.y + y);
- //Debug.Log("Image color: " + imageColor + ", spriteColor: " + spriteColor);
- if (!imageColor.Equals(spriteColor))
- {
- valid = false;
- break;
- }
- }
- }
- Debug.Log("Texture size: " + new Vector2Int(singleTexture.width, singleTexture.height) + ", Sprite size: " + singleSprite.rect.size +
- ", these images are" + (valid ? "" : " not") + " the same");
- }*/
- public void CleanMap()
- {
- for (int y = copyMap.cellBounds.yMin; y <= copyMap.cellBounds.yMax; y++)
- {
- for (int x = copyMap.cellBounds.xMin; x <= copyMap.cellBounds.xMax; x++)
- {
- TileBase mapTile = copyMap.GetTile(new Vector3Int(x, y, 0));
- foreach (TileBase compareTile in cleanTiles)
- if (mapTile == compareTile)
- copyMap.SetTile(new Vector3Int(x, y, 0), null);
- }
- }
- }
- public void ClearMap()
- {
- copyMap.ClearAllTiles();
- }
- }
- public class TileAnalyzeData
- {
- public TileBase tile;
- public Matrix4x4 matrix;
- public TileAnalyzeData(TileBase tile, Matrix4x4 matrix)
- {
- this.tile = tile;
- this.matrix = matrix;
- }
- }
- [CustomEditor(typeof(ImageToLevel))]
- public class ImageToLevelEditor : Editor
- {
- public override void OnInspectorGUI()
- {
- ImageToLevel itl = target as ImageToLevel;
- if (GUILayout.Button(new GUIContent("Analyze", "Analyze the image and convert it to a level")))
- {
- if (itl.autoClean)
- itl.ClearMap();
- double time = EditorApplication.timeSinceStartup;
- int validTiles = itl.AnalyzeImage();
- time = EditorApplication.timeSinceStartup - time;
- float truncatedTime = (float)(Math.Truncate(time * 100.0) / 100.0);
- Debug.Log("Placed " + validTiles + " tiles in " + truncatedTime + " seconds");
- if (itl.autoClean)
- itl.CleanMap();
- }
- DrawDefaultInspector();
- //if (GUILayout.Button(new GUIContent("Analyze single", "Analyze a sprite's data")))
- // t.AnalyzeSprite();
- if (GUILayout.Button(new GUIContent("Clean Tilemap", "Remove selected tiles from the map")))
- itl.CleanMap();
- if (GUILayout.Button(new GUIContent("Clear Tilemap", "Clears the attached tilemap")))
- itl.ClearMap();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement