private void DoLateOnValidate() { EditorApplication.update -= DoLateOnValidate; if (!this || !ParentTilemap) { return; } //Debug.Log("DoLateOnValidate " + ParentTilemap.name + "/" + name, gameObject); // fix prefab preview if (EditorCompatibilityUtils.IsPrefab(gameObject) && !gameObject.scene.IsValid()) { #if !UNITY_2018_3_OR_NEWER // disabled prefab preview for performance issue with new prefab workflow m_needsRebuildMesh = true; UpdateMesh(true); #endif } else { m_needsRebuildMesh = true; m_needsRebuildColliders = true; if (ParentTilemap) //NOTE: this is null sometimes in Unity 2017.2.0b4. It happens when the brush is changed, so maybe it's related with the brush but transform.parent is null. { ParentTilemap.UpdateMesh(); } } }
private void DoLateOnValidate() { EditorApplication.update -= DoLateOnValidate; if (!this || !ParentTilemap) { return; } //Debug.Log("DoLateOnValidate " + ParentTilemap.name + "/" + name, gameObject); // fix prefab preview if (EditorCompatibilityUtils.IsPrefab(gameObject)) { m_needsRebuildMesh = true; UpdateMesh(); } else { m_needsRebuildMesh = true; m_needsRebuildColliders = true; if (ParentTilemap) //NOTE: this is null sometimes in Unity 2017.2.0b4. It happens when the brush is changed, so maybe it's related with the brush but transform.parent is null. { ParentTilemap.UpdateMesh(); } } }
public void DoInspectorGUI() { serializedObject.Update(); TilesetBrush brush = (TilesetBrush)target; if (brush.Tileset == null) { EditorGUILayout.HelpBox("Select a tileset first", MessageType.Info); EditorGUILayout.PropertyField(m_tileset); serializedObject.ApplyModifiedProperties(); return; } EditorGUILayout.PropertyField(m_tileset); EditorGUILayout.PropertyField(m_showInPalette); m_group.intValue = TilesetEditor.DoGroupFieldLayout(brush.Tileset, "Group", m_group.intValue); string sAutotilingModeTooltip = "Autotiling Mode:\n" + "Self: autotile only with brushes of same type\n" + "Other: autotile with any other not empty tile\n" + "Group: autotile with brushes of a group that autotile the brush group"; m_autotilingMode.intValue = System.Convert.ToInt32(EditorCompatibilityUtils.EnumMaskField(new GUIContent("Autotiling Mode", sAutotilingModeTooltip), brush.AutotilingMode)); if (GUI.changed) { serializedObject.ApplyModifiedProperties(); EditorUtility.SetDirty(target); } }
private static void CreatePrefabFromBrush() { if (BrushBehaviour.Exists) { GameObject brushTilemap = CreateTilemapFromBrush(); string path = AssetDatabase.GetAssetOrScenePath(Selection.activeObject); if (string.IsNullOrEmpty(path)) { path = "Assets/"; } path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), brushTilemap.name + ".prefab").Replace(@"\", @"/"); path = AssetDatabase.GenerateUniqueAssetPath(path); GameObject prefab = EditorCompatibilityUtils.CreatePrefab(path, brushTilemap); Selection.activeObject = prefab; EditorGUIUtility.PingObject(prefab); GameObject.DestroyImmediate(brushTilemap); } }
private GameObject CreateTileObject(int tileIdx, TilePrefabData tilePrefabData) { if (tilePrefabData.prefab != null) { TileObjData tileObjData = FindTileObjDataByTileIdx(tileIdx); GameObject tileObj = null; int gx = tileIdx % m_width; int gy = tileIdx / m_width; if (tileObjData == null || tileObjData.tilePrefabData != tilePrefabData || tileObjData.obj == null) { #if UNITY_EDITOR GameObject sourcePrefabInstance = null; if (BrushBehaviour.TileObjSourceTilemap) { // Use the brush instance to copy also the modified parameters Vector2Int copyLoc = new Vector2Int(GridPosX + gx + BrushBehaviour.TileObjSourceTilemapOffset.x, GridPosY + gy + BrushBehaviour.TileObjSourceTilemapOffset.y); sourcePrefabInstance = BrushBehaviour.TileObjSourceTilemap.GetTileObject(copyLoc.x, copyLoc.y); } if (sourcePrefabInstance && !EditorCompatibilityUtils.IsPrefab(sourcePrefabInstance)) { tileObj = (GameObject)Instantiate(sourcePrefabInstance, Vector3.zero, transform.rotation); tileObj.name = tilePrefabData.prefab.name; } else { tileObj = (GameObject)UnityEditor.PrefabUtility.InstantiatePrefab(tilePrefabData.prefab); if (sourcePrefabInstance) { UnityEditor.PropertyModification[] modifications = UnityEditor.PrefabUtility.GetPropertyModifications(sourcePrefabInstance); UnityEditor.PrefabUtility.SetPropertyModifications(tileObj, modifications); } } // allow destroy the object with undo operations if (ParentTilemap.IsUndoEnabled) { UnityEditor.Undo.RegisterCreatedObjectUndo(tileObj, STETilemap.k_UndoOpName + ParentTilemap.name); } #else tileObj = (GameObject)Instantiate(tilePrefabData.prefab, Vector3.zero, transform.rotation); #endif _SetTileObjTransform(tileObj, gx, gy, tilePrefabData, m_tileDataList[tileIdx]); if (tileObjData != null) { m_tileObjToBeRemoved.Add(tileObjData.obj); tileObjData.obj = tileObj; tileObjData.tilePrefabData = tilePrefabData; } else { m_tileObjList.Add(new TileObjData() { tilePos = tileIdx, obj = tileObj, tilePrefabData = tilePrefabData }); } tileObj.SendMessage(k_OnTilePrefabCreation, new OnTilePrefabCreationData() { ParentTilemap = ParentTilemap, GridX = GridPosX + gx, GridY = GridPosY + gy }, SendMessageOptions.DontRequireReceiver); return(tileObj); } else if (tileObjData.obj != null) { #if UNITY_EDITOR && !UNITY_2018_3_OR_NEWER //+++ Break tilemap prefab and restore tile prefab link GameObject parentPrefab = UnityEditor.PrefabUtility.FindRootGameObjectWithSameParentPrefab(tileObjData.obj); if (parentPrefab != tileObjData.obj) { DestroyImmediate(tileObjData.obj); tileObjData.obj = UnityEditor.PrefabUtility.InstantiatePrefab(tileObjData.tilePrefabData.prefab) as GameObject; } ///--- #endif _SetTileObjTransform(tileObjData.obj, gx, gy, tilePrefabData, m_tileDataList[tileIdx]); tileObjData.obj.SendMessage(k_OnTilePrefabCreation, new OnTilePrefabCreationData() { ParentTilemap = ParentTilemap, GridX = GridPosX + gx, GridY = GridPosY + gy }, SendMessageOptions.DontRequireReceiver); return(tileObjData.obj); } } return(null); }
/// <summary> /// Update the mesh and return false if all tiles are empty /// </summary> /// <returns></returns> public bool UpdateMesh() { if (ParentTilemap == null) { if (transform.parent == null) { gameObject.hideFlags = HideFlags.None; //Unhide orphan tilechunks. This shouldn't happen } ParentTilemap = transform.parent.GetComponent <STETilemap>(); } if (gameObject.layer != ParentTilemap.gameObject.layer) { gameObject.layer = ParentTilemap.gameObject.layer; } if (!gameObject.CompareTag(ParentTilemap.gameObject.tag)) { gameObject.tag = ParentTilemap.gameObject.tag; } transform.localPosition = new Vector2(GridPosX * CellSize.x, GridPosY * CellSize.y); if (m_meshFilter.sharedMesh == null) { //Debug.Log("Creating new mesh for " + name); m_meshFilter.sharedMesh = new Mesh(); m_meshFilter.sharedMesh.hideFlags = HideFlags.DontSave; m_meshFilter.sharedMesh.name = ParentTilemap.name + "_mesh"; m_needsRebuildMesh = true; } #if UNITY_EDITOR // fix prefab preview, not compatible with MaterialPropertyBlock. I need to create a new material and change the main texture and color directly. if (EditorCompatibilityUtils.IsPrefab(gameObject)) { gameObject.hideFlags |= HideFlags.HideInHierarchy; if (m_meshRenderer.sharedMaterial == null || m_meshRenderer.sharedMaterial == ParentTilemap.Material) { m_meshRenderer.sharedMaterial = new Material(ParentTilemap.Material); m_meshRenderer.sharedMaterial.name += "_copy"; m_meshRenderer.sharedMaterial.hideFlags = HideFlags.DontSave; m_meshRenderer.sharedMaterial.color = ParentTilemap.TintColor; m_meshRenderer.sharedMaterial.mainTexture = ParentTilemap.Tileset ? ParentTilemap.Tileset.AtlasTexture : null; } } else #endif //NOTE: else above { m_meshRenderer.sharedMaterial = ParentTilemap.Material; } m_meshRenderer.enabled = ParentTilemap.IsVisible; if (m_needsRebuildMesh) { m_needsRebuildMesh = false; if (FillMeshData()) { m_invalidateBrushes = false; Mesh mesh = m_meshFilter.sharedMesh; mesh.Clear(); UpdateSortOrder(); #if UNITY_5_0 || UNITY_5_1 mesh.vertices = s_vertices.ToArray(); mesh.triangles = s_triangles.ToArray(); mesh.uv = m_uv.ToArray(); if (s_colors32 != null && s_colors32.Count != 0) { mesh.colors32 = s_colors32.ToArray(); } else { mesh.colors32 = null; } #else mesh.SetVertices(s_vertices); mesh.SetTriangles(s_triangles, 0); mesh.SetUVs(0, m_uv); if (s_colors32 != null && s_colors32.Count != 0) { mesh.SetColors(s_colors32); } else { mesh.SetColors((List <Color32>)null); } #endif mesh.RecalculateNormals(); //NOTE: allow directional lights to work properly TangentSolver(mesh); //NOTE: allow bumped shaders to work with directional lights } else { return(false); } } else if (m_needsRebuildMeshColor) { UpdateMeshVertexColor(); Mesh mesh = m_meshFilter.sharedMesh; #if UNITY_5_0 || UNITY_5_1 if (s_colors32 != null && s_colors32.Count != 0) { mesh.colors32 = s_colors32.ToArray(); } else { mesh.colors32 = null; } #else if (s_colors32 != null && s_colors32.Count != 0) { mesh.SetColors(s_colors32); } else { mesh.SetColors((List <Color32>)null); } #endif } m_needsRebuildMeshColor = false; return(true); }
private void DoColorSceneGUI() { Event e = Event.current; int controlID = GUIUtility.GetControlID(FocusType.Passive); HandleUtility.AddDefaultControl(controlID); EventType currentEventType = Event.current.GetTypeForControl(controlID); bool skip = false; int saveControl = GUIUtility.hotControl; //Shortcuts if (e.type == EventType.ScrollWheel && e.control) { s_colorSettings.radius += e.delta.y * 0.1f; e.Use(); } try { if (currentEventType == EventType.Layout) { skip = true; } else if (currentEventType == EventType.ScrollWheel) { skip = true; } if (m_tilemap.Tileset == null) { return; } if (!skip) { EditorGUIUtility.AddCursorRect(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), MouseCursor.Arrow); GUIUtility.hotControl = controlID; { Plane chunkPlane = new Plane(m_tilemap.transform.forward, m_tilemap.transform.position); Vector2 mousePos = Event.current.mousePosition; mousePos.y = Screen.height - mousePos.y; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); float dist; if (chunkPlane.Raycast(ray, out dist)) { Vector3 brushWorldPos = ray.GetPoint(dist); // Update brush transform m_localBrushPos = (Vector2)m_tilemap.transform.InverseTransformPoint(brushWorldPos); EditorCompatibilityUtils.CircleCap(0, brushWorldPos, m_tilemap.transform.rotation, s_colorSettings.radius); if ( (EditorWindow.focusedWindow == EditorWindow.mouseOverWindow) && // fix painting tiles when closing another window popup over the SceneView like GameObject Selection window (e.type == EventType.MouseDown || e.type == EventType.MouseDrag) ) { if (e.button == 0) { if (e.alt) { //Color Pickup Color pickedColor = m_tilemap.GetTileColor(m_localBrushPos).c0; pickedColor.a = s_colorSettings.color.a; s_colorSettings.color = pickedColor; } else if (s_colorSettings.paintTilemapGroup && m_tilemap.ParentTilemapGroup) { m_tilemap.ParentTilemapGroup.IterateTilemapWithAction((STETilemap tilemap) => { if (tilemap && tilemap.IsVisible) { if (s_enableUndoColorPainting) { RegisterTilemapUndo(tilemap); } TilemapVertexPaintUtils.VertexPaintCircle(tilemap, m_localBrushPos, s_colorSettings.radius, s_colorSettings.color, s_colorSettings.blendMode, s_colorSettings.tileColorPaintMode == eTileColorPaintMode.Vertex, s_colorSettings.brushIntensity); tilemap.UpdateMesh(); } }); } else { if (s_enableUndoColorPainting) { RegisterTilemapUndo(m_tilemap); } TilemapVertexPaintUtils.VertexPaintCircle(m_tilemap, m_localBrushPos, s_colorSettings.radius, s_colorSettings.color, s_colorSettings.blendMode, s_colorSettings.tileColorPaintMode == eTileColorPaintMode.Vertex, s_colorSettings.brushIntensity); m_tilemap.UpdateMesh(); } } } } } if (currentEventType == EventType.MouseDrag && Event.current.button < 2) // 2 is for central mouse button { // avoid dragging the map Event.current.Use(); } } } // Avoid loosing the hotControl because of a triggered exception catch (System.Exception ex) { Debug.LogException(ex); } SceneView.RepaintAll(); GUIUtility.hotControl = saveControl; }
public override void OnInspectorGUI() { serializedObject.Update(); if (m_prevTileset != m_brush.Tileset) { if (m_prevTileset) { m_prevTileset.OnBrushSelected -= OnBrushSelected; m_prevTileset.OnTileSelected -= OnTileSelected; } OnDisable(); OnEnable(); } m_prevTileset = m_brush.Tileset; base.OnInspectorGUI(); if (!m_brush.Tileset) { return; } Vector2 visualTileSize = m_brush.Tileset.VisualTileSize; EditorGUILayout.Space(); GUILayoutUtility.GetRect(1f, 1f, GUILayout.Width(visualTileSize.x), GUILayout.Height(visualTileSize.y)); Rect rSelectedTile = GUILayoutUtility.GetLastRect(); uint tileData = m_brush.GetAnimTileData(); if (tileData != Tileset.k_TileData_Empty) { rSelectedTile.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, rSelectedTile.center.y); GUI.Box(new Rect(rSelectedTile.position - Vector2.one, rSelectedTile.size + 2 * Vector2.one), ""); TilesetEditor.DoGUIDrawTileFromTileData(rSelectedTile, tileData, m_brush.Tileset); } EditorGUILayout.Space(); SerializedProperty randomFlagMaskProperty = serializedObject.FindProperty("RandomizeFlagMask"); System.Enum enumNew = EditorCompatibilityUtils.EnumMaskField(new GUIContent("Random Flags", "Applies random flags when painting tiles"), (eRandomFlags)(randomFlagMaskProperty.longValue >> 29)); randomFlagMaskProperty.longValue = ((long)System.Convert.ChangeType(enumNew, typeof(long)) & 0x7) << 29; uint brushTileData = m_randTileList.index >= 0 ? m_brush.RandomTileList[m_randTileList.index].tileData : Tileset.k_TileData_Empty; brushTileData = BrushTileGridControl.DoTileDataPropertiesLayout(brushTileData, m_brush.Tileset, false); if (m_randTileList.index >= 0) { m_brush.RandomTileList[m_randTileList.index].tileData = brushTileData; } EditorGUILayout.Space(); EditorGUILayout.HelpBox("Activate this to use animated brushes as random tiles", MessageType.Info); EditorGUILayout.PropertyField(serializedObject.FindProperty("RemoveBrushIdAfterRefresh")); // Draw List m_randTileList.elementHeight = visualTileSize.y + 35f; m_randTileList.DoLayoutList(); if (Event.current.type == EventType.Repaint) { m_randTileListHasFocus = m_randTileList.HasKeyboardControl(); } TileSelection tileSelection = ((TilesetBrush)target).Tileset.TileSelection; if (tileSelection != null) { if (GUILayout.Button("Add tiles from tile selection")) { m_brush.RandomTileList.AddRange(tileSelection.selectionData.Select(x => new RandomBrush.RandomTileData() { tileData = x, probabilityFactor = 1f })); } } EditorGUILayout.HelpBox("Select a tile from list and then select a tile from tile selection window.", MessageType.Info); EditorGUILayout.HelpBox("Add and Remove tiles with '+' and '-' buttons.", MessageType.Info); Repaint(); serializedObject.ApplyModifiedProperties(); if (GUI.changed) { m_brush.InvalidateSortedList(); EditorUtility.SetDirty(target); } }