Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Stop refreshing Tiles in the Scene View

Discussion in '2D' started by blu3drag0n, Nov 22, 2018.

  1. blu3drag0n

    blu3drag0n

    Joined:
    Nov 9, 2018
    Posts:
    94
    Good morning,
    so I have tried yesterday myself 3 hours to find a solution for this, but every post didn't solve my problem.

    I'm working with the Tilemap feature in Unity and scripted a Scriptable Tile having that code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.Tilemaps;
    6.  
    7. [System.Serializable, ExecuteInEditMode]
    8. public class RandomTile : Tile
    9. {
    10.     public TilesAndChances[] AllTiles;
    11.     private Sprite preview;
    12.  
    13.     public override void RefreshTile(Vector3Int position, ITilemap tilemap)
    14.     {
    15.  
    16.         if (OnGUIHandler.CurrentlyClicking)
    17.         {
    18.             tilemap.RefreshTile(position);
    19.         }
    20.     }
    21.  
    22.     public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
    23.     {
    24.         int chancesSum = 0;
    25.         foreach (TilesAndChances tac in AllTiles)
    26.         {
    27.             chancesSum += tac.Chance;        
    28.         }
    29.  
    30.         if(chancesSum > 0)
    31.         {
    32.             int gambled = Random.Range(1, chancesSum);
    33.             int counter = -1;
    34.             while (gambled >= AllTiles[++counter].Chance)
    35.             {
    36.                 gambled -= AllTiles[counter].Chance;
    37.             }
    38.             tileData.sprite = AllTiles[counter].Tile;
    39.         }
    40.     }
    41.  
    42. #if UNITY_EDITOR
    43.     [MenuItem("Assets/Create/Tiles/Ground/MixedGrass")]
    44.     public static void CreateMixedGrassTile()
    45.     {
    46.         string path = EditorUtility.SaveFilePanelInProject("Save MixedGrass", "MixedGrass", "asset", "Save mixed grass tile", "Assets");
    47.         if (path == "")
    48.         {
    49.             return;
    50.         }
    51.         AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<AllGrounds_GrassMixed_TileSet>(), path);
    52.     }
    53.  
    54.     #endif
    55.  
    56.     [System.Serializable]
    57.     public class TilesAndChances
    58.     {
    59.         public Sprite Tile;
    60.         public int Chance;
    61.     }
    62. }
    63.  

    I fill in the inspector an array size of 10 and all the Sprites and Chances.
    Then I am able to start painting on a Tilemap and it always paints me a random tile out of the 10 by chance, given in the chance value.
    So far so good and as wanted.

    But then when I'm hovering through the already painted tiles it always regenerates a new Tile.
    Furthermore on every single Codechange Unity regenerated every single Tile new.

    This makes it impossible for me to find a "good map" and leave it as is.

    What I want is to paint it and leave it forever unchanged, BUT when I have my left mouse button down, then the Tiles should be painted/refreshed(if already exists on that position)

    I've tried with everything e.g.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. using UnityEngine.Tilemaps;
    6.  
    7. [ExecuteInEditMode]
    8. [CustomEditor(typeof(RandomTile))]
    9. public class OnGUIHandler : Editor {
    10.  
    11.     public static bool CurrentlyClicking=false;
    12.  
    13.     /*void OnGUI()
    14.     {
    15.         Debug.Log("Current event detected 2: " + Event.current.type);
    16.     }*/
    17.  
    18.     void OnSceneGUI()
    19.     {
    20.         Debug.Log("Current event detected: " + Event.current.type);
    21.         CurrentlyClicking = true;
    22.     }
    23. }
    24.  

    But I don't even know what kind of Object Unity is painting on the Tilemap, so I don't know what Class should be given on the "CustomEditor(typeof())"

    I just want that to work in Editor mode, when I paint on the Scene View.

    I've also tried such things within the code
    Code (CSharp):
    1.    
    2. void OnGUI()  //or OnSceneGUI()
    3.     {
    4.         Event e = Event.current;
    5.         int controlID = GUIUtility.GetControlID(FocusType.Passive);
    6.         switch (e.GetTypeForControl(controlID))
    7.         {
    8.             case EventType.MouseDown:
    9.                 OnGUIHandler.CurrentlyClicking = true;
    10.                 Debug.Log("mouse down");
    11.                 break;
    12.             case EventType.MouseUp:
    13.                 OnGUIHandler.CurrentlyClicking = false;
    14.                 Debug.Log("mouse up");
    15.                 break;
    16.         }
    17.     }
    or
    Code (CSharp):
    1.  
    2. void OnSceneGUI (){
    3.      Event e = Event.current;
    4.      int controlID = GUIUtility.GetControlID (FocusType.Passive);
    5.      switch (e.GetTypeForControl (controlID)) {
    6.      case EventType.MouseDown:
    7.          GUIUtility.hotControl = controlID;    
    8.          CurrentlyClicking = true;
    9.          e.Use ();
    10.          break;
    11.      case EventType.MouseUp:
    12.          GUIUtility.hotControl = 0;
    13.          CurrentlyClicking = false;
    14.          break;
    15.      }
    16.      AllDrawingStuff();
    17. }
    But I don't get it to work :(

    Even the OnSceneGUI or OnGUI Events are NEVER called, doesn't matter how I play around with the derives or where I store these functions.
    Tried with deriving from Editor, EditorWindow, MonoBehaviour and so on, combined the Eventhandling snippets within my custom Tileset or in another Class...

    Anyone has a good idea how can I handle EVERY mousclick(and mouse held) within the scene View, no matter what kind of Object I am painting or any other solution so I get this to run , it's very annoying every "cool arrangement of the Tilemap" is getting destroyed OnLoad and OnHovering.

    Thanks in advance!!

    KR,
    blue
     
    Last edited: Nov 22, 2018
  2. blu3drag0n

    blu3drag0n

    Joined:
    Nov 9, 2018
    Posts:
    94
    I've managed to implement a comprehensive and very satisfying solution for all of my needs and issue from before + some more features.
    I will start an article regarding this and will share this to everybody.
    Maybe less people face Tilemap- / Tile managing & Editor Mode handling issues then :)
     
  3. _Eyesgood_

    _Eyesgood_

    Joined:
    Apr 19, 2013
    Posts:
    55
    Did you publish your article yet?