public override void OnInspectorGUI() { AutoTileLookup lookup = target as AutoTileLookup; showBaseInspector = EditorGUILayout.Foldout(showBaseInspector, "Show Base Inspector"); if (showBaseInspector) { base.OnInspectorGUI(); } overrideRulesFromTile = EditorGUILayout.Foldout(overrideRulesFromTile, "Override Rules List"); if (overrideRulesFromTile) { EditorGUILayout.BeginVertical(GUI.skin.box); { EditorGUILayout.LabelField( "This will set the target rules for this lookup to match. " + "You don't need to use this unless you are creating a new lookup.", GUI.skin.box); RuleTile load = (RuleTile)EditorGUILayout.ObjectField("Load Ruleset", null, typeof(RuleTile), false); if (load) { lookup.m_maskValues = load.m_TilingRules; } } EditorGUILayout.EndVertical(); } showSubTileMapping = EditorGUILayout.Foldout(showSubTileMapping, "Show Subtile Mapping"); if (showSubTileMapping) { EditorGUILayout.BeginVertical(GUI.skin.box); { EditorGUILayout.LabelField( "This shows each Rule (set with the override tile rules parameter.) " + "Alongside each rule is the lookup data for each quadrant of the tile.", GUI.skin.box); } EditorGUILayout.EndVertical(); SubTileMappingGUI(lookup); } EditorGUILayout.BeginVertical(GUI.skin.box); { EditorGUILayout.LabelField( "This will take the texture and generate " + "the appropriate assets + RuleTile data.", GUI.skin.box); Texture2D texture = (Texture2D)EditorGUILayout.ObjectField(null, typeof(Texture2D), false); if (texture != null) { ImportAutotile.ImportSubtile(texture, lookup); } } EditorGUILayout.EndVertical(); }
private void SubTileMappingGUI(AutoTileLookup lookup) { int totalInts = TILECOUNT * SUBTILES; if (lookup.m_TileQuads == null) { lookup.m_TileQuads = new int[totalInts]; EditorUtility.SetDirty(lookup); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); return; } if (lookup.m_TileQuads.Length != totalInts) { EditorGUILayout.LabelField("error with TileQuads param"); if (GUILayout.Button("Fix/Reset")) { lookup.m_TileQuads = new int[totalInts]; EditorUtility.SetDirty(lookup); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); return; } return; } EditorGUI.BeginChangeCheck(); for (int i = 0; i < TILECOUNT; i++) { EditorGUILayout.BeginHorizontal("box"); if (lookup.m_maskValues != null && lookup.m_maskValues.Count > i) { TileMaskGUI(lookup.m_maskValues[i]); } EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); lookup.m_TileQuads[i * 4] = EditorGUILayout.IntField(lookup.m_TileQuads[i * 4]); lookup.m_TileQuads[(i * 4) + 1] = EditorGUILayout.IntField(lookup.m_TileQuads[(i * 4) + 1]); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); lookup.m_TileQuads[(i * 4) + 2] = EditorGUILayout.IntField(lookup.m_TileQuads[(i * 4) + 2]); lookup.m_TileQuads[(i * 4) + 3] = EditorGUILayout.IntField(lookup.m_TileQuads[(i * 4) + 3]); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(lookup); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } }
static void ProcessFullsizeTexture(Texture2D selectedTexture, AutoTileLookup lookup) { string assetName = selectedTexture.name; if (!AssetDatabase.IsValidFolder("Assets/Autotiles")) { string rootGuid = AssetDatabase.CreateFolder("Assets", "Autotiles"); } string folderGuid = AssetDatabase.CreateFolder("Assets/Autotiles", assetName); string folderName = AssetDatabase.GUIDToAssetPath(folderGuid); Vector2Int TileResolution = new Vector2Int( selectedTexture.width / 4, selectedTexture.height / 6); AssetDatabase.Refresh(); RuleTile m_tile = ScriptableObject.CreateInstance <RuleTile>(); m_tile.m_TilingRules = new List <RuleTile.TilingRule>(); int count = 0; for (int i = 255; i >= 0; i--) { RuleTile.TilingRule rule = GetRule(i); if (rule != null) { m_tile.m_TilingRules.Add(rule); GenerateSprites(count, TileResolution.x, selectedTexture, lookup, folderName); count++; } } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); for (int i = 0; i < m_tile.m_TilingRules.Count; i++) { m_tile.m_TilingRules[i].m_Sprites = new Sprite[1]; m_tile.m_TilingRules[i].m_Sprites[0] = AssetDatabase.LoadAssetAtPath <Sprite>(folderName + "/" + selectedTexture.name + i + ".png"); } AssetDatabase.CreateAsset(m_tile, folderName + "/" + assetName + "tile.asset"); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
static void ProcessSubtileTexture(Texture2D _texture, AutoTileLookup _lookup) { //Spprite importer stuff to prep the asset for slicing. string path = AssetDatabase.GetAssetPath(_texture); var importer = AssetImporter.GetAtPath(path) as TextureImporter; importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; importer.mipmapEnabled = false; importer.filterMode = FilterMode.Point; importer.spritePivot = Vector2.down; importer.textureCompression = TextureImporterCompression.Uncompressed; var textureSettings = new TextureImporterSettings(); importer.ReadTextureSettings(textureSettings); textureSettings.spriteMeshType = SpriteMeshType.FullRect; textureSettings.spriteExtrude = 0; importer.SetTextureSettings(textureSettings); //for A2s we know the subtil size is width/4 int minSpriteSize = _texture.width / 4; //Slice the asset Rect[] rects = InternalSpriteUtility.GenerateGridSpriteRectangles( _texture, Vector2.zero, new Vector2(minSpriteSize, minSpriteSize), Vector2.zero); List <Rect> rectList = new List <Rect>(rects); string filenameNoExtension = Path.GetFileNameWithoutExtension(path); List <SpriteMetaData> metas = new List <SpriteMetaData>(); int count = 0; foreach (Rect rect in rectList) { var meta = new SpriteMetaData(); meta.pivot = Vector2.one * 0.5f;//center meta.alignment = (int)SpriteAlignment.Center; meta.rect = rect; int xpos = count % 4; int ypos = Mathf.CeilToInt(count / 4); int rightside = xpos % 2; int topside = (ypos + 1) % 2; int lookup = (topside * 2) + rightside; meta.name = RuleTileEditor.m_ModDirections[lookup] + count.ToString("00") + "_" + filenameNoExtension; metas.Add(meta); count++; } importer.spritesheet = metas.ToArray(); AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); Object[] objects = AssetDatabase.LoadAllAssetsAtPath(path); List <Sprite> sprites = new List <Sprite>(); for (int i = 0; i < objects.Length; i++) { //filter out non-sprites. I was getting some extra entry here. if ((objects[i] as Sprite) != null) { sprites.Add(objects[i] as Sprite); } } sprites.Sort((Sprite x, Sprite y) => x.name.CompareTo(y.name)); RuleTile m_tile = ScriptableObject.CreateInstance <RuleTile>(); m_tile.m_TilingRules = new List <RuleTile.TilingRule>(); int rulecount = 0; for (int i = 255; i >= 0; i--) { RuleTile.TilingRule rule = ImportAutotile.GetRule(i); if (rule != null) { AddSpritesToRule(ref rule, sprites, rulecount, _lookup); rulecount++; m_tile.m_TilingRules.Add(rule); } } AssetDatabase.CreateAsset(m_tile, "Assets/" + filenameNoExtension + "tile.asset"); }
static void AddSpritesToRule(ref RuleTile.TilingRule _rule, List <Sprite> _sprites, int _ruleID, AutoTileLookup _lookup) { _rule.m_Sprites = new Sprite[4]; _rule.m_Output = RuleTile.TilingRule.OutputSprite.Modulo; // 0 sw, 1 se, 2 nw, 3 ne int[] lookups = { (_ruleID * 4) + 2, (_ruleID * 4) + 3, (_ruleID * 4) + 0, (_ruleID * 4) + 1 }; int[] tileIDs = { _lookup.m_TileQuads[lookups[0]], _lookup.m_TileQuads[lookups[1]], _lookup.m_TileQuads[lookups[2]], _lookup.m_TileQuads[lookups[3]] }; //how do we go from tileid to sprite? //sprites are in alphabetical order based on importer settings //its a fixed layout on the A2, so 6 tiles total, 4 subtiles each. //NE->NW->SE->SW _rule.m_Sprites[0] = _sprites[18 + tileIDs[0]]; _rule.m_Sprites[1] = _sprites[12 + tileIDs[1]]; _rule.m_Sprites[2] = _sprites[6 + tileIDs[2]]; _rule.m_Sprites[3] = _sprites[tileIDs[3]]; }
static public void ImportSubtile(Object _image, AutoTileLookup _lookup) { Texture2D texture = _image as Texture2D; ProcessSubtileTexture(texture, _lookup); }
static void GenerateSprites(int neighbourMask, int res, Texture2D source, AutoTileLookup lookup, string folderPath) { //pull the asset coords from our lookup table. int TL = lookup.m_TileQuads[neighbourMask * 4]; int TR = lookup.m_TileQuads[(neighbourMask * 4) + 1]; int BL = lookup.m_TileQuads[(neighbourMask * 4) + 2]; int BR = lookup.m_TileQuads[(neighbourMask * 4) + 3]; //from Tile IDs to SubtileIDs TL = 20 - (TL * 4) + ((TL % 2) * 6); TR = 20 - (TR * 4) + ((TR % 2) * 6); BL = 20 - (BL * 4) + ((BL % 2) * 6); BR = 20 - (BR * 4) + ((BR % 2) * 6); TR += 1; BL -= 4; BR -= 3; Vector2Int TLcoord = new Vector2Int(TL % 4, TL / 4); Vector2Int TRcoord = new Vector2Int(TR % 4, TR / 4); Vector2Int BLcoord = new Vector2Int(BL % 4, BL / 4); Vector2Int BRcoord = new Vector2Int(BR % 4, BR / 4); Texture2D tex = new Texture2D(res * 2, res * 2); Vector2Int localIndex = new Vector2Int(0, 0); for (int texX = 0; texX < tex.width / 2; texX++) { localIndex.y = 0; for (int texY = res; texY < res * 2; texY++) { Color sample = source.GetPixel( (TLcoord.x * res) + localIndex.x, (TLcoord.y * res) + localIndex.y); tex.SetPixel(texX, texY, sample); localIndex.y++; } localIndex.y = 0; for (int texY = 0; texY < res; texY++) { Color sample = source.GetPixel( (BLcoord.x * res) + localIndex.x, (BLcoord.y * res) + localIndex.y); tex.SetPixel(texX, texY, sample); localIndex.y++; } localIndex.x++; } localIndex.x = 0; for (int texX = res; texX < res * 2; texX++) { localIndex.y = 0; for (int texY = res; texY < res * 2; texY++) { Color sample = source.GetPixel( (TRcoord.x * res) + localIndex.x, (TRcoord.y * res) + localIndex.y); tex.SetPixel(texX, texY, sample); localIndex.y++; } localIndex.y = 0; for (int texY = 0; texY < res; texY++) { Color sample = source.GetPixel( (BRcoord.x * res) + localIndex.x, (BRcoord.y * res) + localIndex.y); tex.SetPixel(texX, texY, sample); localIndex.y++; } localIndex.x++; } byte[] bytes = tex.EncodeToPNG(); File.WriteAllBytes(folderPath + "/" + source.name + neighbourMask + ".png", bytes); }
static public void ImportFullsizeAsset(Object _image, AutoTileLookup _lookup) { Texture2D selectedTexture = _image as Texture2D; ProcessFullsizeTexture(selectedTexture, _lookup); }