Пример #1
0
        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();
                }
            }
        }
Пример #2
0
        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();
                }
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
 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);
     }
 }
Пример #5
0
        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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        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;
        }
Пример #8
0
        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);
            }
        }