Last active
November 6, 2021 21:53
-
-
Save tklee1975/747477d47d03cb1a26ae790555c6f3e3 to your computer and use it in GitHub Desktop.
Simple Road Auto Tile Logic (#unity #scriptable_tile)
This file contains hidden or 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
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| using UnityEngine; | |
| using UnityEngine.Tilemaps; | |
| #if UNITY_EDITOR | |
| using UnityEditor; | |
| #endif | |
| // | |
| [Serializable] | |
| public class SimpleRoadTile : TileBase { | |
| public Sprite[] spriteList = new Sprite[4]; // | |
| // Constant | |
| // Constant for Direction | |
| const int UP = 1 << 0; | |
| const int DOWN = 1 << 1; | |
| const int LEFT = 1 << 2; | |
| const int RIGHT = 1 << 3; | |
| // Constant for sprite | |
| // note for the sprite | |
| // STRAIGHT TURN 3WAY CROSS | |
| // # # # # | |
| // # ## ### ### | |
| // # # | |
| const int SPRITE_IDX_STRAIGHT = 0; | |
| const int SPRITE_IDX_TURN = 1; | |
| const int SPRITE_IDX_3WAY = 2; | |
| const int SPRITE_IDX_CROSS = 3; | |
| public override void RefreshTile(Vector3Int location, ITilemap tilemap) | |
| { | |
| // UP, DOWN LEFT, RIGHT | |
| List<Vector3Int> refreshPosList = new List<Vector3Int> (); | |
| refreshPosList.Add (location + new Vector3Int ( 1, 0, 0)); | |
| refreshPosList.Add (location + new Vector3Int (-1, 0, 0)); | |
| refreshPosList.Add (location + new Vector3Int ( 0, 0, 0)); // Need to refresh the given location too | |
| refreshPosList.Add (location + new Vector3Int ( 0, 1, 0)); | |
| refreshPosList.Add (location + new Vector3Int ( 0, -1, 0)); | |
| // Refresh the given position | |
| foreach(Vector3Int position in refreshPosList) { | |
| if (HasRoadTile (tilemap, position)) { | |
| tilemap.RefreshTile (position); | |
| } | |
| } | |
| } | |
| public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData) | |
| { | |
| Debug.Log ("GetTileData: location=" + location); | |
| int mask = HasRoadTile(tileMap, location + new Vector3Int(0, 1, 0)) ? UP : 0; | |
| mask += HasRoadTile(tileMap, location + new Vector3Int(0, -1, 0)) ? DOWN : 0; | |
| mask += HasRoadTile(tileMap, location + new Vector3Int(1, 0, 0)) ? RIGHT : 0; | |
| mask += HasRoadTile(tileMap, location + new Vector3Int(-1, 0, 0)) ? LEFT : 0; | |
| Vector2Int spriteAndRotation = GetSpriteAndRotation (mask); | |
| int spriteIndex = spriteAndRotation.x; | |
| int rotation = spriteAndRotation.y; | |
| Sprite sprite = spriteList [spriteIndex]; | |
| if (sprite == null) { | |
| return; | |
| } | |
| Matrix4x4 rotationMatrix = GetRotationMatrix (rotation); | |
| // Update the TileData | |
| tileData.transform = rotationMatrix; | |
| tileData.sprite = sprite; | |
| tileData.color = Color.white; | |
| tileData.flags = TileFlags.LockAll; | |
| } | |
| private Matrix4x4 GetRotationMatrix(int rotation) { | |
| Quaternion quaternion = Quaternion.Euler(0f, 0f, -rotation); | |
| Matrix4x4 mat = Matrix4x4.identity; | |
| mat.SetTRS(Vector3.zero, quaternion, Vector3.one); | |
| return mat; | |
| } | |
| // Return Vector2Int : | |
| // vector.x = Sprite Index | |
| // vector.y = Sprite Rotation | |
| // | |
| // Note for the Sprite | |
| // | |
| private Vector2Int GetSpriteAndRotation(int mask) | |
| { | |
| switch (mask) | |
| { | |
| // one connection | |
| case UP: | |
| case DOWN: | |
| { | |
| return new Vector2Int (SPRITE_IDX_STRAIGHT, 0); | |
| } | |
| case LEFT: | |
| case RIGHT: | |
| { | |
| return new Vector2Int (SPRITE_IDX_STRAIGHT, 90); | |
| } | |
| // two connection (No turn) | |
| case (UP | DOWN): | |
| { | |
| return new Vector2Int (SPRITE_IDX_STRAIGHT, 0); | |
| } | |
| case (LEFT | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_STRAIGHT, 90); | |
| } | |
| // two connection (turn) | |
| case (UP | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_TURN, 0); | |
| } | |
| case (DOWN | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_TURN, 90); | |
| } | |
| case (DOWN | LEFT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_TURN, 180); | |
| } | |
| case (UP | LEFT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_TURN, 270); | |
| } | |
| // three connection | |
| case (UP | LEFT | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_3WAY, 0); | |
| } | |
| case (UP | DOWN | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_3WAY, 90); | |
| } | |
| case (DOWN | LEFT | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_3WAY, 180); | |
| } | |
| case (UP | DOWN | LEFT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_3WAY, 270); | |
| } | |
| // four connection | |
| case (UP | DOWN | LEFT | RIGHT): | |
| { | |
| return new Vector2Int (SPRITE_IDX_CROSS, 0); | |
| } | |
| default: | |
| { | |
| return new Vector2Int (SPRITE_IDX_STRAIGHT, 0); | |
| } | |
| } | |
| } | |
| // This determines if the Tile at the position is also using RoadTile (same scriptable object). | |
| private bool HasRoadTile(ITilemap tilemap, Vector3Int position) | |
| { | |
| return tilemap.GetTile(position) == this; | |
| } | |
| #if UNITY_EDITOR | |
| [MenuItem("Assets/Create/Custom Tile/SimpleRoadTile")] | |
| public static void CreateTile() | |
| { | |
| string path = EditorUtility.SaveFilePanelInProject("Save SimpleRoadTile", | |
| "SimpleRoadTile", "asset", "Save SimpleRoadTile", "Assets"); | |
| if (path == "") { | |
| return; | |
| } | |
| AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<SimpleRoadTile>(), path); | |
| } | |
| #endif | |
| } |
This file contains hidden or 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
| using System; | |
| using System.Collections; | |
| using System.Collections.Generic; | |
| #if UNITY_EDITOR | |
| using UnityEditor; | |
| #endif | |
| using UnityEngine; | |
| #if UNITY_EDITOR | |
| [CustomEditor(typeof(SimpleRoadTile))] | |
| public class SimpleRoadTileEditor : Editor | |
| { | |
| private SimpleRoadTile tile { get { return (target as SimpleRoadTile); } } | |
| public void OnEnable() | |
| { | |
| if (tile.spriteList == null || tile.spriteList.Length != 4) | |
| { | |
| tile.spriteList = new Sprite[4]; | |
| EditorUtility.SetDirty(tile); | |
| } | |
| } | |
| public override void OnInspectorGUI() | |
| { | |
| EditorGUI.BeginChangeCheck(); | |
| int idx; | |
| string name; | |
| // | |
| idx = SimpleRoadTile.SPRITE_IDX_STRAIGHT; | |
| name = "Straight"; | |
| tile.spriteList[idx] = (Sprite) EditorGUILayout.ObjectField(name, tile.spriteList[idx], typeof(Sprite), false, null); | |
| idx = SimpleRoadTile.SPRITE_IDX_TURN; | |
| name = "Turn"; | |
| tile.spriteList[idx] = (Sprite) EditorGUILayout.ObjectField(name, tile.spriteList[idx], typeof(Sprite), false, null); | |
| idx = SimpleRoadTile.SPRITE_IDX_3WAY; | |
| name = "3Ways"; | |
| tile.spriteList[idx] = (Sprite) EditorGUILayout.ObjectField(name, tile.spriteList[idx], typeof(Sprite), false, null); | |
| idx = SimpleRoadTile.SPRITE_IDX_CROSS; | |
| name = "Cross"; | |
| tile.spriteList[idx] = (Sprite) EditorGUILayout.ObjectField(name, tile.spriteList[idx], typeof(Sprite), false, null); | |
| if (EditorGUI.EndChangeCheck ()) { | |
| EditorUtility.SetDirty (tile); | |
| } | |
| } | |
| } | |
| #endif | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment