private void DisplayAutotiling() { if (Tileset.SelectedBrushId != Tileset.k_BrushId_Default) { TilesetBrush brush = Tileset.FindBrush(Tileset.SelectedBrushId); if (brush) { EditorGUILayout.BeginHorizontal(); GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y)); TilesetEditor.DoGUIDrawTileFromTileData(GUILayoutUtility.GetLastRect(), brush.GetAnimTileData(), Tileset, brush.GetAnimUV()); GUILayout.Label("(" + brush.name + ":" + brush.GetType().Name + ")", EditorStyles.boldLabel); EditorGUILayout.EndHorizontal(); if (!m_brushEditor || m_brushEditor.target != brush) { m_brushEditor = TilesetBrushEditor.CreateEditor(brush) as TilesetBrushEditor; } (m_brushEditor as TilesetBrushEditor).DoInspectorGUI(); } } else { bool isMultiselection = Tileset.TileSelection != null; Tile selectedTile = isMultiselection ? Tileset.Tiles[(int)(Tileset.TileSelection.selectionData[0] & Tileset.k_TileDataMask_TileId)] : Tileset.SelectedTile; GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y)); Rect tileUV = selectedTile.uv; GUI.color = Tileset.BackgroundColor; GUI.DrawTextureWithTexCoords(GUILayoutUtility.GetLastRect(), EditorGUIUtility.whiteTexture, tileUV, true); GUI.color = Color.white; GUI.DrawTextureWithTexCoords(GUILayoutUtility.GetLastRect(), Tileset.AtlasTexture, tileUV, true); if (isMultiselection) { EditorGUILayout.LabelField("* Multi-selection Edition", EditorStyles.boldLabel); } EditorGUI.BeginChangeCheck(); selectedTile.autilingGroup = TilesetEditor.DoGroupFieldLayout(Tileset, "Group", selectedTile.autilingGroup); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(Tileset, "Tile Autotiling Data Changed"); if (isMultiselection) { for (int i = 0; i < Tileset.TileSelection.selectionData.Count; ++i) { Tile tile = Tileset.Tiles[(int)(Tileset.TileSelection.selectionData[i] & Tileset.k_TileDataMask_TileId)]; tile.autilingGroup = selectedTile.autilingGroup; } } EditorUtility.SetDirty(Tileset); } } }
public static void TileDataField(Rect position, GUIContent label, SerializedProperty property, Tileset tileset) { Event e = Event.current; bool isLeftMouseReleased = e.type == EventType.MouseUp && e.button == 0; //NOTE: there is a bug with DrawTextureWithTexCoords where the texture disappears. It is fixed by overriding the Editor Script with a CustomEditor. Rect rVisualTile = new Rect(position.x, position.y, k_TilePreviewSize, k_TilePreviewSize); uint tileData = (uint)property.intValue; TilesetBrush brush = tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData)); if (brush) { tileData = brush.PreviewTileData(); } TilesetEditor.DoGUIDrawTileFromTileData(rVisualTile, tileData, tileset); if (isLeftMouseReleased && rVisualTile.Contains(e.mousePosition)) { EditorWindow wnd = EditorWindow.focusedWindow; TileSelectionWindow.Show(tileset); TileSelectionWindow.Instance.Ping(); wnd.Focus(); GUI.FocusControl(""); } EditorGUI.PropertyField(new Rect(position.x, position.y + k_TilePreviewSize, position.width, position.height - k_TilePreviewSize), property, label); }
public bool AutotileWith(int selfBrushId, int otherBrushId) { if ( ((AutotilingMode & eAutotilingMode.Self) != 0 && selfBrushId == otherBrushId) || ((AutotilingMode & eAutotilingMode.Other) != 0 && otherBrushId != selfBrushId && otherBrushId != (Tileset.k_TileDataMask_BrushId >> 16)) ) { return(true); } else if ((AutotilingMode & eAutotilingMode.Group) != 0) { TilesetBrush brush = Tileset.FindBrush(otherBrushId); if (brush) { return(Tileset.GetGroupAutotiling(Group, brush.Group)); } } return(false); }
public static uint DoTileDataPropertiesLayout(uint tileData, Tileset tileset, bool displayBrush = true) { EditorGUILayout.BeginVertical(EditorStyles.helpBox); GUI.enabled = tileData != Tileset.k_TileData_Empty; EditorGUIUtility.labelWidth = 100; EditorGUI.BeginChangeCheck(); EditorGUILayout.Toggle("Flip Horizontally", (tileData & Tileset.k_TileFlag_FlipH) != 0); if (EditorGUI.EndChangeCheck()) { tileData ^= Tileset.k_TileFlag_FlipH; } EditorGUI.BeginChangeCheck(); EditorGUILayout.Toggle("Flip Vertically", (tileData & Tileset.k_TileFlag_FlipV) != 0); if (EditorGUI.EndChangeCheck()) { tileData ^= Tileset.k_TileFlag_FlipV; } EditorGUI.BeginChangeCheck(); EditorGUILayout.Toggle("Rotate 90º", (tileData & Tileset.k_TileFlag_Rot90) != 0); if (EditorGUI.EndChangeCheck()) { tileData ^= Tileset.k_TileFlag_Rot90; } if (displayBrush) { EditorGUI.BeginChangeCheck(); int brushId = Tileset.GetBrushIdFromTileData(tileData); TilesetBrush brush = tileset.FindBrush(brushId); brush = (TilesetBrush)EditorGUILayout.ObjectField("Brush", brush, typeof(TilesetBrush), false); if (EditorGUI.EndChangeCheck()) { brushId = brush != null?tileset.FindBrushId(brush.name) : Tileset.k_BrushId_Default; int tileId = brush != null ? (int)(brush.PreviewTileData() & Tileset.k_TileDataMask_TileId) : Tileset.GetTileIdFromTileData(tileData); tileData &= Tileset.k_TileDataMask_Flags; tileData |= (uint)(brushId << 16) & Tileset.k_TileDataMask_BrushId; tileData |= (uint)(tileId & Tileset.k_TileDataMask_TileId); } } if (GUILayout.Button("Reset")) { tileData = Tileset.k_TileData_Empty; } EditorGUIUtility.labelWidth = 0; GUI.enabled = true; EditorGUILayout.EndVertical(); return(tileData); }
public override uint[] GetSubtiles(Tilemap tilemap, int gridX, int gridY, uint tileData) { // Add animated tiles { int idx = CalculateIndex(tilemap, gridX, gridY, tileData); TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(TileIds[idx])); if (brush && brush.IsAnimated()) { TilemapChunk.RegisterAnimatedBrush(brush); } } return(null); }
public bool AutotileWith(int selfBrushId, int otherBrushId) { if ( ((AutotilingMode & eAutotilingMode.Self) != 0 && selfBrushId == otherBrushId) || ((AutotilingMode & eAutotilingMode.Other) != 0 && otherBrushId != selfBrushId && otherBrushId != (Tileset.k_TileDataMask_BrushId >> 16)) ) { return(true); } if ((AutotilingMode & eAutotilingMode.Group) != 0) { TilesetBrush brush = Tileset.FindBrush(otherBrushId); if (brush) { return(Tileset.GetGroupAutotiling(Group, brush.Group)); } else if (otherBrushId == Tileset.k_BrushId_Default) { return(Tileset.GetGroupAutotiling(Group, 0)); //with normal tiles, use default group (0) //TODO: this is old code, now it is possible to change tile group. Check if this method is useful after removing it from TilemapChunk } } return(false); }
/// <summary> /// Return a tile parameter (bool, int, float, string or UnityEngine.Object) from a tiledata. /// It takes first the parameter from a brush, if possible, then from a tile. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tileset"></param> /// <param name="tileData"></param> /// <param name="paramName"></param> /// <param name="defaultValue"></param> /// <returns></returns> static public T GetTileParameter <T>(Tileset tileset, uint tileData, string paramName, T defaultValue = default(T)) { Tile tile = tileset.GetTile(Tileset.GetTileIdFromTileData(tileData)); TilesetBrush brush = tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData)); T value = defaultValue; if (brush) { value = brush.Params.GetParam <T>(paramName, defaultValue); } if (tile != null && EqualityComparer <T> .Default.Equals(value, defaultValue)) { value = tile.paramContainer.GetParam <T>(paramName, defaultValue); } return(value); }
public override uint Refresh(STETilemap tilemap, int gridX, int gridY, uint tileData) { if (RandomTileList.Count > 0) { uint randomTileData = GetRandomTile(); if (RandomizeFlagMask != 0) { uint flags = ((uint)Random.Range(0, 8) << 29) & RandomizeFlagMask; randomTileData &= ~RandomizeFlagMask; randomTileData |= flags; } uint brushTileData = RefreshLinkedBrush(tilemap, gridX, gridY, randomTileData); // overwrite flags brushTileData &= ~Tileset.k_TileDataMask_Flags; brushTileData |= randomTileData & Tileset.k_TileDataMask_Flags; TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(brushTileData)); if (brush && brush.IsAnimated()) { // Set the animated brush (overwriting the random brush for this tile) brushTileData &= ~Tileset.k_TileDataMask_BrushId; brushTileData |= randomTileData & Tileset.k_TileDataMask_BrushId; } // Overwrite the brush id for the one in the selected random tile // Side Effect: the tile will loose the brush id for the random brush if (RemoveBrushIdAfterRefresh) { // Do nothing } // Overwrite the selected tile brush id for the random brush id // NOTE: animated tiles wont be animated else { // overwrite brush id brushTileData &= ~Tileset.k_TileDataMask_BrushId; brushTileData |= tileData & Tileset.k_TileDataMask_BrushId; } return(brushTileData); } return(tileData); }
public override uint Refresh(Tilemap tilemap, int gridX, int gridY, uint tileData) { if (RandomTileList.Count > 0) { uint randomTileData = GetRandomTile(); if (RandomizeFlagMask != 0) { uint flags = ((uint)Random.Range(0, 8) << 29) & RandomizeFlagMask; randomTileData &= ~RandomizeFlagMask; randomTileData |= flags; } uint brushTileData = RefreshLinkedBrush(tilemap, gridX, gridY, randomTileData); // overwrite flags brushTileData &= ~Tileset.k_TileDataMask_Flags; brushTileData |= randomTileData & Tileset.k_TileDataMask_Flags; TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(brushTileData)); if (brush && brush.IsAnimated()) { // Set the animated brush (overwriting the random brush for this tile) brushTileData &= ~Tileset.k_TileDataMask_BrushId; brushTileData |= randomTileData & Tileset.k_TileDataMask_BrushId; } // - Commented: // This code will make the Random Brush to work only once // Copy the tile will copy the tile placed the first time // - Uncommented: // This code will make Refresh Tilemap to update all random brushes // Copy the tile will copy a random brush tile /* * { * // overwrite brush id * brushTileData &= ~Tileset.k_TileDataMask_BrushId; * brushTileData |= tileData & Tileset.k_TileDataMask_BrushId; * }*/ return(brushTileData); } return(tileData); }
/// <summary> /// Get the parameter container from tileData if tileData contains a tile with parameters or Null in other case /// </summary> static public ParameterContainer GetParamsFromTileData(Tileset tileset, uint tileData) { int brushId = Tileset.GetBrushIdFromTileData(tileData); TilesetBrush brush = tileset.FindBrush(brushId); if (brush) { return(brush.Params); } else { int tileId = Tileset.GetTileIdFromTileData(tileData); Tile tile = tileset.GetTile(tileId); if (tile != null) { return(tile.paramContainer); } } return(null); }
public override uint[] GetSubtiles(STETilemap tilemap, int gridX, int gridY, uint tileData) { // Add animated tiles { int brushId = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16); bool autotiling_N = AutotileWith(tilemap, brushId, gridX, gridY + 1); bool autotiling_E = AutotileWith(tilemap, brushId, gridX + 1, gridY); bool autotiling_S = AutotileWith(tilemap, brushId, gridX, gridY - 1); bool autotiling_W = AutotileWith(tilemap, brushId, gridX - 1, gridY); int idx = 0; if (autotiling_N) { idx = 1; } if (autotiling_E) { idx |= 2; } if (autotiling_S) { idx |= 4; } if (autotiling_W) { idx |= 8; } TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(TileIds[idx])); if (brush && brush.IsAnimated()) { TilemapChunk.RegisterAnimatedBrush(brush); } } return(null); }
private void DisplayParameters() { Event e = Event.current; TileSelection tileSelection = Tileset.TileSelection; if (tileSelection != null) { EditorGUILayout.LabelField("Multi-tile editing not allowed", EditorStyles.boldLabel); } else { UnityEngine.Object prevOwner = m_parameterListOwner; if (Tileset.SelectedBrushId != Tileset.k_BrushId_Default) { m_parameterListOwner = Tileset.FindBrush(Tileset.SelectedBrushId); } else { m_parameterListOwner = Tileset; } if (m_parameterListOwner != null) { if (prevOwner != m_parameterListOwner || Tileset.SelectedTileId != m_prevSelectedTileId || m_tileParameterList == null) { m_prevSelectedTileId = Tileset.SelectedTileId; m_tileParameterList = CreateParameterReorderableList(m_parameterListOwner is Tileset ? ((Tileset)m_parameterListOwner).SelectedTile.paramContainer : ((TilesetBrush)m_parameterListOwner).Params); m_tileParameterList.onChangedCallback += (ReorderableList list) => { EditorUtility.SetDirty(m_parameterListOwner); }; } GUILayoutUtility.GetRect(1, 1, GUILayout.Width(Tileset.VisualTileSize.x), GUILayout.Height(Tileset.VisualTileSize.y)); uint tilePreviewData = m_parameterListOwner is Tileset ? (uint)(((Tileset)m_parameterListOwner).SelectedTileId & Tileset.k_TileDataMask_TileId) : ((TilesetBrush)m_parameterListOwner).GetAnimTileData(); Rect customUV = m_parameterListOwner is Tileset ? default(Rect) : ((TilesetBrush)m_parameterListOwner).GetAnimUV(); GUI.color = Tileset.BackgroundColor; GUI.DrawTexture(GUILayoutUtility.GetLastRect(), EditorGUIUtility.whiteTexture); GUI.color = Color.white; TilesetEditor.DoGUIDrawTileFromTileData(GUILayoutUtility.GetLastRect(), tilePreviewData, Tileset, customUV); m_tileParamScrollViewPos = EditorGUILayout.BeginScrollView(m_tileParamScrollViewPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); EditorGUI.BeginChangeCheck(); m_tileParameterList.DoLayoutList(); Rect rList = GUILayoutUtility.GetLastRect(); if (e.isMouse && !rList.Contains(e.mousePosition)) { m_tileParameterList.ReleaseKeyboardFocus(); m_tileParameterList.index = -1; } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(m_parameterListOwner); } EditorGUILayout.EndScrollView(); } } }
public static uint DoTileDataProperties(Rect position, uint tileData, Tileset tileset, bool displayBrush = true) { position.height = 90f; GUI.BeginGroup(position, EditorStyles.helpBox); { GUI.enabled = tileData != Tileset.k_TileData_Empty; EditorGUIUtility.labelWidth = 100; Rect fieldRect = new Rect(2f, 2f, position.width - 4f, EditorGUIUtility.singleLineHeight); EditorGUI.BeginChangeCheck(); EditorGUI.Toggle(fieldRect, "Flip Horizontally", (tileData & Tileset.k_TileFlag_FlipH) != 0); if (EditorGUI.EndChangeCheck()) { tileData ^= Tileset.k_TileFlag_FlipH; } fieldRect.y += EditorGUIUtility.singleLineHeight; EditorGUI.BeginChangeCheck(); EditorGUI.Toggle(fieldRect, "Flip Vertically", (tileData & Tileset.k_TileFlag_FlipV) != 0); if (EditorGUI.EndChangeCheck()) { tileData ^= Tileset.k_TileFlag_FlipV; } fieldRect.y += EditorGUIUtility.singleLineHeight; EditorGUI.BeginChangeCheck(); EditorGUI.Toggle(fieldRect, "Rotate 90º", (tileData & Tileset.k_TileFlag_Rot90) != 0); if (EditorGUI.EndChangeCheck()) { tileData ^= Tileset.k_TileFlag_Rot90; } if (displayBrush) { fieldRect.y += EditorGUIUtility.singleLineHeight; EditorGUI.BeginChangeCheck(); int brushId = Tileset.GetBrushIdFromTileData(tileData); TilesetBrush brush = tileset.FindBrush(brushId); brush = (TilesetBrush)EditorGUI.ObjectField(fieldRect, "Brush", brush, typeof(TilesetBrush), false); if (EditorGUI.EndChangeCheck()) { if (brush && brush.Tileset != tileset) { Debug.LogWarning("The brush " + brush.name + " belongs to a different tileset and cannot be selected! "); } else { brushId = brush != null?tileset.FindBrushId(brush.name) : Tileset.k_BrushId_Default; int tileId = brush != null ? (int)(brush.PreviewTileData() & Tileset.k_TileDataMask_TileId) : Tileset.GetTileIdFromTileData(tileData); tileData &= Tileset.k_TileDataMask_Flags; tileData |= (uint)(brushId << 16) & Tileset.k_TileDataMask_BrushId; tileData |= (uint)(tileId & Tileset.k_TileDataMask_TileId); } } } fieldRect.y += EditorGUIUtility.singleLineHeight + 4f; fieldRect.x += 2f; fieldRect.width -= 4f; if (GUI.Button(fieldRect, "Reset")) { tileData = Tileset.k_TileData_Empty; } EditorGUIUtility.labelWidth = 0; GUI.enabled = true; } GUI.EndGroup(); return(tileData); }
// '°', '├', '═', '┤', | 0, 2, 10, 8, // '┬', '╔', '╦', '╗', | 4, 6, 14, 12, // '║', '╠', '╬', '╣', | 5, 7, 15, 13, // '┴', '╚', '╩', '╝', | 1, 3, 11, 9, public override uint[] GetSubtiles(STETilemap tilemap, int gridX, int gridY, uint tileData) { CalculateNeighbourData(tilemap, gridX, gridY, tileData); // tiles that need subtile division if (s_needsSubTiles) { uint[] aSubTileData = null; if (s_neighIdx == 0) //° { aSubTileData = new uint[] { TileIds[3], TileIds[9], TileIds[6], TileIds[12] }; } else if (s_neighIdx == 4)//┬ { aSubTileData = new uint[] { TileIds[6], TileIds[12], TileIds[6], TileIds[12] }; } else if (s_neighIdx == 5)//║ { aSubTileData = new uint[] { TileIds[7], TileIds[13], TileIds[7], TileIds[13] }; } else if (s_neighIdx == 1)//┴ { aSubTileData = new uint[] { TileIds[3], TileIds[9], TileIds[3], TileIds[9] }; } else if (s_neighIdx == 2)//├ { aSubTileData = new uint[] { TileIds[3], TileIds[3], TileIds[6], TileIds[6] }; } else if (s_neighIdx == 10)//═ { aSubTileData = new uint[] { TileIds[11], TileIds[11], TileIds[14], TileIds[14] }; } else if (s_neighIdx == 8)//┤ { aSubTileData = new uint[] { TileIds[9], TileIds[9], TileIds[12], TileIds[12] }; } // NOTE: this case '╬' cut the tiles different (using corner tiles). // If it is commented, and default case is used, instead or corner tiles, it will use the center tile '╬' // Depending on the graphics it could be interesting add a check box to choose between using this or not. else if (s_neighIdx == 15)// ╬ { aSubTileData = new uint[] { InteriorCornerTileIds[0], InteriorCornerTileIds[1], InteriorCornerTileIds[2], InteriorCornerTileIds[3] }; } else { aSubTileData = new uint[] { TileIds[s_neighIdx], TileIds[s_neighIdx], TileIds[s_neighIdx], TileIds[s_neighIdx] }; } for (int i = 0; i < s_showDiagonal.Length; ++i) { aSubTileData[i] = RefreshLinkedBrush(tilemap, gridX, gridY, aSubTileData[i]); if (s_showDiagonal[i]) { aSubTileData[i] = InteriorCornerTileIds[3 - i]; } // Add animated tiles { TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(aSubTileData[i])); if (brush && brush.IsAnimated()) { TilemapChunk.RegisterAnimatedBrush(brush, i); } } } return(aSubTileData); } // Add animated tiles { TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(s_tileData)); if (brush && brush.IsAnimated()) { TilemapChunk.RegisterAnimatedBrush(brush); } } return(null); }
private void UpdateMeshVertexColor() { //Debug.Log( "[" + ParentTilemap.name + "] FillData -> " + name); if (!Tileset || !Tileset.AtlasTexture) { return; } int totalTiles = m_width * m_height; if (s_colors32 == null) { s_colors32 = new List <Color32>(totalTiles * 4); } else { s_colors32.Clear(); } for (int ty = 0, tileIdx = 0; ty < m_height; ++ty) { for (int tx = 0; tx < m_width; ++tx, ++tileIdx) { uint tileData = m_tileDataList[tileIdx]; if (tileData != Tileset.k_TileData_Empty) { int brushId = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16); int tileId = (int)(tileData & Tileset.k_TileDataMask_TileId); Tile tile = Tileset.GetTile(tileId); TilesetBrush tileBrush = null; if (brushId > 0) { tileBrush = Tileset.FindBrush(brushId); } uint[] subtileData = tileBrush != null?tileBrush.GetSubtiles(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData) : null; if (subtileData == null) { if (tile != null) { if (tile.prefabData.prefab == null || tile.prefabData.showTileWithPrefab || //hide the tiles with prefabs ( unless showTileWithPrefab is true ) tileBrush && tileBrush.IsAnimated()) // ( skip if it's an animated brush ) { if (m_tileColorList != null && m_tileColorList.Count > tileIdx) { TileColor32 tileColor32 = m_tileColorList[tileIdx]; s_colors32.Add(tileColor32.c0); s_colors32.Add(tileColor32.c1); s_colors32.Add(tileColor32.c2); s_colors32.Add(tileColor32.c3); } } } } else { for (int i = 0; i < subtileData.Length; ++i) { //if (tileUV != default(Rect)) //NOTE: if this is uncommented, there won't be coherence with geometry ( 16 vertices per tiles with subtiles ). But it means also, the tile shouldn't be null. { if (m_tileColorList != null && m_tileColorList.Count > tileIdx) { TileColor32 tileColor32 = m_tileColorList[tileIdx]; Color32 middleColor = new Color32( System.Convert.ToByte((tileColor32.c0.r + tileColor32.c1.r + tileColor32.c2.r + tileColor32.c3.r) >> 2), System.Convert.ToByte((tileColor32.c0.g + tileColor32.c1.g + tileColor32.c2.g + tileColor32.c3.g) >> 2), System.Convert.ToByte((tileColor32.c0.b + tileColor32.c1.b + tileColor32.c2.b + tileColor32.c3.b) >> 2), System.Convert.ToByte((tileColor32.c0.a + tileColor32.c1.a + tileColor32.c2.a + tileColor32.c3.a) >> 2) ); switch (i) { case 0: s_colors32.Add(tileColor32.c0); s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c0, .5f)); s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c0, .5f)); s_colors32.Add(middleColor); break; case 1: s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c1, .5f)); s_colors32.Add(tileColor32.c1); s_colors32.Add(middleColor); s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c1, .5f)); break; case 2: s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c2, .5f)); s_colors32.Add(middleColor); s_colors32.Add(tileColor32.c2); s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c2, .5f)); break; case 3: s_colors32.Add(middleColor); s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c3, .5f)); s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c3, .5f)); s_colors32.Add(tileColor32.c3); break; } } } } } } } } }
/* * private void DummyDeepProfilingFix() * { * // For some reason, in Unity 2017.3.1f1, the Deep Profiling crashes unless FillMeshData call any method, even a dummy method like this * // Other weird thing is, the crash doesn't happens if one case of the switch statement is commented * // FINALLY: the fix was to change the Switch for if-else statements. I keep this notes just in case to remember about this weird issue. * } */ /// <summary> /// Fill the mesh data and return false if all tiles are empty /// </summary> /// <returns></returns> private bool FillMeshData() { //Debug.Log( "[" + ParentTilemap.name + "] FillData -> " + name); //DummyDeepProfilingFix(); if (!Tileset || !Tileset.AtlasTexture) { return(false); } s_currUpdatedTilechunk = this; int totalTiles = m_width * m_height; if (s_vertices == null) { s_vertices = new List <Vector3>(totalTiles * 4); } else { s_vertices.Clear(); } if (s_triangles == null) { s_triangles = new List <int>(totalTiles * 6); } else { s_triangles.Clear(); } if (s_colors32 == null) { s_colors32 = new List <Color32>(totalTiles * 4); } else { s_colors32.Clear(); } if (m_uv == null) { m_uv = new List <Vector2>(totalTiles * 4); } else { m_uv.Clear(); } Vector2[] subTileOffset = new Vector2[] { new Vector2(0f, 0f), new Vector2(CellSize.x / 2f, 0f), new Vector2(0f, CellSize.y / 2f), new Vector2(CellSize.x / 2f, CellSize.y / 2f), }; Vector2 subTileSize = CellSize / 2f; m_animatedTiles.Clear(); bool isEmpty = true; for (int ty = 0, tileIdx = 0; ty < m_height; ++ty) { for (int tx = 0; tx < m_width; ++tx, ++tileIdx) { uint tileData = m_tileDataList[tileIdx]; if (tileData != Tileset.k_TileData_Empty) { int brushId = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16); int tileId = (int)(tileData & Tileset.k_TileDataMask_TileId); Tile tile = Tileset.GetTile(tileId); TilesetBrush tileBrush = null; if (tileId >= 0 && tile == null && brushId <= 0) { Debug.LogWarning(ParentTilemap.name + "\\" + name + ": TileId " + tileId + " not found! GridPos(" + (GridPosX + tx) + "," + (GridPosY + ty) + ") tilaData 0x" + tileData.ToString("X")); m_tileDataList[tileIdx] = Tileset.k_TileData_Empty; } if (brushId > 0) { tileBrush = Tileset.FindBrush(brushId); if (tileBrush == null) { Debug.LogWarning(ParentTilemap.name + "\\" + name + ": BrushId " + brushId + " not found! GridPos(" + (GridPosX + tx) + "," + (GridPosY + ty) + ") tilaData 0x" + tileData.ToString("X")); m_tileDataList[tileIdx] = tileData & ~Tileset.k_TileDataMask_BrushId; } if (tileBrush != null && (m_invalidateBrushes || (tileData & Tileset.k_TileFlag_Updated) == 0)) { tileData = tileBrush.Refresh(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData); //+++NOTE: this code add support for animated brushes inside a random brush // Collateral effects of supporting changing the brush id in Refresh: // - When the random brush select a tile data with another brush id, this tile won't be a random tile any more // - If the tilemap is refreshed several times, and at least a tile data contains another brush id, then all tiles will loose the brush id of the random brush if (BrushBehaviour.Instance.BrushTilemap == ParentTilemap) // avoid changing brushId when updating the BrushTilemap { tileData &= ~Tileset.k_TileDataMask_BrushId; tileData |= (uint)(brushId << 16); } int newBrushId = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16); if (brushId != newBrushId) { brushId = newBrushId; tileBrush = Tileset.FindBrush(brushId); } //--- tileData |= Tileset.k_TileFlag_Updated; // set updated flag m_tileDataList[tileIdx] = tileData; // update tileData tileId = (int)(tileData & Tileset.k_TileDataMask_TileId); tile = Tileset.GetTile(tileId); // update created objects if (tile != null && tile.prefabData.prefab != null) { CreateTileObject(tileIdx, tile.prefabData); } else { DestroyTileObject(tileIdx); } } } isEmpty = false; if (tileBrush != null && tileBrush.IsAnimated()) { m_animatedTiles.Add(new AnimTileData() { VertexIdx = s_vertices.Count, Brush = tileBrush, SubTileIdx = -1 }); } s_currUVVertex = s_vertices.Count; Rect tileUV; uint[] subtileData = tileBrush != null?tileBrush.GetSubtiles(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData) : null; if (subtileData == null) { if (tile != null) { if (tile.prefabData.prefab == null || tile.prefabData.showTileWithPrefab || //hide the tiles with prefabs ( unless showTileWithPrefab is true ) tileBrush && tileBrush.IsAnimated()) // ( skip if it's an animated brush ) { tileUV = tile.uv; _AddTileToMesh(tileUV, tx, ty, tileData, Vector2.zero, CellSize); if (m_tileColorList != null && m_tileColorList.Count > tileIdx) { TileColor32 tileColor32 = m_tileColorList[tileIdx]; s_colors32.Add(tileColor32.c0); s_colors32.Add(tileColor32.c1); s_colors32.Add(tileColor32.c2); s_colors32.Add(tileColor32.c3); } } } } else { for (int i = 0; i < subtileData.Length; ++i) { uint subTileData = subtileData[i]; int subTileId = (int)(subTileData & Tileset.k_TileDataMask_TileId); Tile subTile = Tileset.GetTile(subTileId); tileUV = subTile != null ? subTile.uv : default(Rect); //if (tileUV != default(Rect)) //NOTE: if this is uncommented, there won't be coherence with geometry ( 16 vertices per tiles with subtiles ). But it means also, the tile shouldn't be null. { _AddTileToMesh(tileUV, tx, ty, subTileData, subTileOffset[i], subTileSize, i); if (m_tileColorList != null && m_tileColorList.Count > tileIdx) { TileColor32 tileColor32 = m_tileColorList[tileIdx]; Color32 middleColor = new Color32( System.Convert.ToByte((tileColor32.c0.r + tileColor32.c1.r + tileColor32.c2.r + tileColor32.c3.r) >> 2), System.Convert.ToByte((tileColor32.c0.g + tileColor32.c1.g + tileColor32.c2.g + tileColor32.c3.g) >> 2), System.Convert.ToByte((tileColor32.c0.b + tileColor32.c1.b + tileColor32.c2.b + tileColor32.c3.b) >> 2), System.Convert.ToByte((tileColor32.c0.a + tileColor32.c1.a + tileColor32.c2.a + tileColor32.c3.a) >> 2) ); //switch(i) // FIX Deep Profiling crash in Unity 2017.3.1f1 see: DummyDeepProfilingFix notes { if (i == 0) { s_colors32.Add(tileColor32.c0); s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c0, .5f)); s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c0, .5f)); s_colors32.Add(middleColor); } else if (i == 1) { s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c1, .5f)); s_colors32.Add(tileColor32.c1); s_colors32.Add(middleColor); s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c1, .5f)); } else if (i == 2) { s_colors32.Add(Color32.Lerp(tileColor32.c0, tileColor32.c2, .5f)); s_colors32.Add(middleColor); s_colors32.Add(tileColor32.c2); s_colors32.Add(Color32.Lerp(tileColor32.c3, tileColor32.c2, .5f)); } else if (i == 3) { s_colors32.Add(middleColor); s_colors32.Add(Color32.Lerp(tileColor32.c1, tileColor32.c3, .5f)); s_colors32.Add(Color32.Lerp(tileColor32.c2, tileColor32.c3, .5f)); s_colors32.Add(tileColor32.c3); } } } } } } } } } //NOTE: the destruction of tileobjects needs to be done here to avoid a Undo/Redo bug. Check inside DestroyTileObject for more information. for (int i = 0; i < m_tileObjToBeRemoved.Count; ++i) { DestroyTileObject(m_tileObjToBeRemoved[i]); } m_tileObjToBeRemoved.Clear(); s_currUpdatedTilechunk = null; return(!isEmpty); }
/// <summary> /// Fill the mesh data and return false if all tiles are empty /// </summary> /// <returns></returns> private bool FillMeshData() { //Debug.Log( "[" + ParentTilemap.name + "] FillData -> " + name); if (Tileset == null) { return(false); } int totalTiles = m_width * m_height; if (m_vertices == null) { m_vertices = new List <Vector3>(totalTiles * 4); m_uv = new List <Vector2>(totalTiles * 4); m_triangles = new List <int>(totalTiles * 6); } else { m_vertices.Clear(); m_triangles.Clear(); m_uv.Clear(); } //+++ MeshCollider if (m_meshCollVertices == null) { m_meshCollVertices = new List <Vector3>(totalTiles * 4); m_meshCollTriangles = new List <int>(totalTiles * 6); } else { m_meshCollVertices.Clear(); m_meshCollTriangles.Clear(); } TileColliderData testCollData = new TileColliderData(); testCollData.vertices = new Vector2[4] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }; //--- Vector2[] subTileOffset = new Vector2[] { new Vector2(0f, 0f), new Vector2(CellSize.x / 2f, 0f), new Vector2(0f, CellSize.y / 2f), new Vector2(CellSize.x / 2f, CellSize.y / 2f), }; Vector2 subTileSize = CellSize / 2f; m_animatedTiles.Clear(); bool isEmpty = true; for (int ty = 0, tileIdx = 0; ty < m_height; ++ty) { for (int tx = 0; tx < m_width; ++tx, ++tileIdx) { uint tileData = m_tileDataList[tileIdx]; if (tileData != Tileset.k_TileData_Empty) { int brushId = (int)((tileData & Tileset.k_TileDataMask_BrushId) >> 16); int tileId = (int)(tileData & Tileset.k_TileDataMask_TileId); Tile tile = (tileId != Tileset.k_TileId_Empty) ? Tileset.Tiles[tileId] : null; TilesetBrush tileBrush = null; if (brushId > 0) { tileBrush = Tileset.FindBrush(brushId); if (tileBrush == null) { Debug.LogWarning(ParentTilemap.name + "\\" + name + ": BrushId " + brushId + " not found! GridPos(" + tx + "," + ty + ") tilaData 0x" + tileData.ToString("X")); m_tileDataList[tileIdx] = tileData & ~Tileset.k_TileDataMask_BrushId; } if (tileBrush != null && (m_invalidateBrushes || (tileData & Tileset.k_TileFlag_Updated) == 0)) { tileData = tileBrush.Refresh(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData); tileData |= Tileset.k_TileFlag_Updated; // set updated flag m_tileDataList[tileIdx] = tileData; // update tileData tileId = (int)(tileData & Tileset.k_TileDataMask_TileId); tile = (tileId != Tileset.k_TileId_Empty) ? Tileset.Tiles[tileId] : null; // update created objects if (tile != null && tile.prefabData.prefab != null) { CreateTileObject(tileIdx, tile.prefabData); } else { DestroyTileObject(tileIdx); } } } isEmpty = false; if (tileBrush != null && tileBrush.IsAnimated()) { m_animatedTiles.Add(new AnimTileData() { VertexIdx = m_vertices.Count, Brush = tileBrush }); } Rect tileUV; uint[] subtileData = tileBrush != null?tileBrush.GetSubtiles(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData) : null; if (subtileData == null) { if (tile != null) { if (tile.prefabData.prefab == null || tile.prefabData.showTileWithPrefab || //hide the tiles with prefabs ( unless showTileWithPrefab is true ) tileBrush && tileBrush.IsAnimated()) // ( skip if it's an animated brush ) { tileUV = tile.uv; _AddTileToMesh(tileUV, tx, ty, tileData, Vector2.zero, CellSize); } } } else { for (int i = 0; i < subtileData.Length; ++i) { uint subTileData = subtileData[i]; int subTileId = (int)(subTileData & Tileset.k_TileDataMask_TileId); tileUV = subTileId != Tileset.k_TileId_Empty ? Tileset.Tiles[subTileId].uv : default(Rect); //if (tileUV != default(Rect)) //NOTE: if this is uncommented, there won't be coherence with geometry ( 16 vertices per tiles with subtiles ). But it means also, the tile shouldn't be null. { _AddTileToMesh(tileUV, tx, ty, subTileData, subTileOffset[i], subTileSize, i); } } } } } } //NOTE: the destruction of tileobjects needs to be done here to avoid a Undo/Redo bug. Check inside DestroyTileObject for more information. for (int i = 0; i < m_tileObjToBeRemoved.Count; ++i) { DestroyTileObject(m_tileObjToBeRemoved[i]); } m_tileObjToBeRemoved.Clear(); return(!isEmpty); }