예제 #1
0
        private void OnNeighborBoxClick(Rect neighborBoxRectangle, ScriptedTile.Rule rule, Dictionary <Vector3Int, int> neighbors, Vector3Int neighborBoxPositionOnMatrix)
        {
            if (Event.current.type == EventType.MouseDown && MouseOnPosition(neighborBoxRectangle))
            {
                neighborRuleCodes = EnumRuleCodeToListRuleCode();

                // Se já houver um Neighbor associado a um NeighborBox.
                if (neighbors.ContainsKey(neighborBoxPositionOnMatrix))
                {
                    int currentRuleCode = neighborRuleCodes.IndexOf(neighbors[neighborBoxPositionOnMatrix]);
                    int changedRuleCode = currentRuleCode + GetChangedClick();

                    if (changedRuleCode >= 0 && changedRuleCode < neighborRuleCodes.Count)
                    {
                        changedRuleCode = (int)Mathf.Repeat(changedRuleCode, neighborRuleCodes.Count);
                        neighbors[neighborBoxPositionOnMatrix] = neighborRuleCodes[changedRuleCode];
                    }
                    else
                    {
                        neighbors.Remove(neighborBoxPositionOnMatrix);
                    }
                }
                else
                {
                    // Se não houver um Neighbor associado a um NeighborBox.
                    neighbors.Add(neighborBoxPositionOnMatrix, neighborRuleCodes[GetChangedClick() == 1 ? 0 : (neighborRuleCodes.Count - 1)]);
                }

                rule.SetNeighbors(neighbors);

                GUI.changed = true;
                Event.current.Use();
            }
        }
예제 #2
0
        private void OnRLAddElement(ReorderableList list)
        {
            ScriptedTile.Rule rule = new ScriptedTile.Rule();

            // Use default values.
            rule.tileSprites[0]   = scriptedTile.defaultTileSprite;
            rule.tileGameObject   = scriptedTile.defaultTileGameObject;
            rule.tileColliderType = scriptedTile.defaultTileColliderType;
            rule.spriteOutputType = ScriptedTile.RuleTileData.SpriteOutputType.Single;

            scriptedTile.rules.Add(rule);
        }
예제 #3
0
        private void OnCenteredNeighborBoxClick(Rect neighborBoxPositionOnMatrix, ScriptedTile.Rule rule)
        {
            if (Event.current.type == EventType.MouseDown && MouseOnPosition(neighborBoxPositionOnMatrix))
            {
                rule.nextTileSelectionType = (ScriptedTile.RuleTileData.RotationType)(int) Mathf.Repeat(
                    (int)rule.nextTileSelectionType + GetChangedClick(),
                    Enum.GetValues(typeof(ScriptedTile.RuleTileData.RotationType)).Length
                    );

                GUI.changed = true;
                Event.current.Use();
            }
        }
예제 #4
0
        private float GetRLElementHeight(int ruleIndex)
        {
            ScriptedTile.Rule rule = scriptedTile.rules[ruleIndex];

            BoundsInt neighborsMatrixBounds = GetNeighborsMatrixBounds(rule.GetNeighborsMatrixBoundsBySelectedNeighbors());

            float heightByTileDataComponent = 0f;
            float sumOfFieldPaddingTop;
            float sumOfheightOfAllSpritesFields;

            switch (rule.spriteOutputType)
            {
            case ScriptedTile.RuleTileData.SpriteOutputType.Single:
                heightByTileDataComponent = ReorderableListGUIDefaults.ElementHeight + ReorderableListGUIDefaults.ElementPaddingHeight + ReorderableListGUIDefaults.FieldPaddingTop * 3;
                break;

            case ScriptedTile.RuleTileData.SpriteOutputType.Random:
                // Iniciar com 6 Fields.
                sumOfFieldPaddingTop = ReorderableListGUIDefaults.FieldPaddingTop * 6;

                for (int i = 0; i < rule.tileSprites.Length; i++)
                {
                    sumOfFieldPaddingTop += ReorderableListGUIDefaults.FieldPaddingTop;
                }

                sumOfheightOfAllSpritesFields = ReorderableListGUIDefaults.FieldHeight * (rule.tileSprites.Length + 3);

                heightByTileDataComponent = sumOfFieldPaddingTop + sumOfheightOfAllSpritesFields + ReorderableListGUIDefaults.ElementHeight + ReorderableListGUIDefaults.ElementPaddingHeight;
                break;

            case ScriptedTile.RuleTileData.SpriteOutputType.Animation:
                // Iniciar com 5 Fields.
                sumOfFieldPaddingTop = ReorderableListGUIDefaults.FieldPaddingTop * 5;

                for (int i = 0; i < rule.tileSprites.Length; i++)
                {
                    sumOfFieldPaddingTop += ReorderableListGUIDefaults.FieldPaddingTop;
                }

                sumOfheightOfAllSpritesFields = ReorderableListGUIDefaults.FieldHeight * (rule.tileSprites.Length + 2);

                heightByTileDataComponent = sumOfFieldPaddingTop + sumOfheightOfAllSpritesFields + ReorderableListGUIDefaults.ElementHeight + ReorderableListGUIDefaults.ElementPaddingHeight;
                break;
            }

            float neighborsMatrixGUIHeight = TransformNeighborsMatrixBoundsToGUI(neighborsMatrixBounds).y + 10f;

            // Qual componente tem a maior altura? TileDataComponent ou NeighborMatrixBounds.
            return(Mathf.Max(heightByTileDataComponent, neighborsMatrixGUIHeight));
        }
예제 #5
0
        private Rect GetFieldRectangle(string label, float componentPositionX, ref float fieldPositionY, ref int fieldOrderNumber, Rect componentRectangle, ScriptedTile.Rule rule)
        {
            Rect labelRectangle = new Rect(
                componentPositionX,
                fieldPositionY + GetFieldPaddingTopByFieldPositionY(fieldPositionY, fieldOrderNumber),
                ReorderableListGUIDefaults.FieldWidth,
                ReorderableListGUIDefaults.FieldHeight
                );

            Rect fieldRectangle = new Rect(
                componentPositionX + ReorderableListGUIDefaults.FieldWidth,
                fieldPositionY + GetFieldPaddingTopByFieldPositionY(fieldPositionY, fieldOrderNumber),

                /*
                 * `componentRectangle.width`: A largura do Field é proporcional a largura do element do ReorderableList,
                 * pois, `componentRectangle` é baseado no elementRectangle.
                 */
                componentRectangle.width - ReorderableListGUIDefaults.FieldWidth,
                ReorderableListGUIDefaults.FieldHeight
                );

            GUI.Label(labelRectangle, label);

            fieldPositionY   = UpdateFieldPositionY(fieldPositionY);
            fieldOrderNumber = UpdateFieldOrderNumber(fieldOrderNumber);

            return(fieldRectangle);
        }
예제 #6
0
        private void InNeighborBox(Vector3Int neighborBoxPositionOnMatrix, Rect neighborBoxRectangle, ScriptedTile.Rule rule, Dictionary <Vector3Int, int> neighbors)
        {
            using (var changeCheckScope = new EditorGUI.ChangeCheckScope()) {
                // Todos os NeighborBox, exceto o do meio.
                if (neighborBoxPositionOnMatrix.x != 0 || neighborBoxPositionOnMatrix.y != 0)
                {
                    if (neighbors.ContainsKey(neighborBoxPositionOnMatrix))
                    {
                        DrawArrowIcons(neighborBoxRectangle, neighborBoxPositionOnMatrix, neighbors[neighborBoxPositionOnMatrix]);
                        OnMouseHoverPrintTooltipByNeighborBox(neighborBoxRectangle, neighbors[neighborBoxPositionOnMatrix]);
                    }

                    OnNeighborBoxClick(neighborBoxRectangle, rule, neighbors, neighborBoxPositionOnMatrix);
                }
                else
                {
                    OnCenteredNeighborBoxClick(neighborBoxRectangle, rule);
                    DrawRotationsIcons(neighborBoxRectangle, rule.nextTileSelectionType);
                }
            }
        }
예제 #7
0
 private void DrawSpriteComponent(Rect spriteComponentRectangle, ScriptedTile.Rule rule)
 {
     rule.tileSprites[0] = EditorGUI.ObjectField(spriteComponentRectangle, rule.tileSprites[0], typeof(Sprite), false) as Sprite;
 }
예제 #8
0
        private void DrawNeighborsMatrixComponent(Rect neighborsMatrixComponentRectangle, BoundsInt neighborsMatrixBounds, ScriptedTile scriptedTile, ScriptedTile.Rule rule)
        {
            Handles.color = EditorGUIUtility.isProSkin ?
                            new Color(1f, 1f, 1f, 0.2f) :
                            new Color(0f, 0f, 0f, 0.2f);

            // Largura do Matrix GUI.
            float matrixWidth = neighborsMatrixComponentRectangle.width;
            // Altura do Matrix GUI.
            float matrixHeight = neighborsMatrixComponentRectangle.height;

            // Quantidade de colunas verticais do Matrix.
            float boundsWidth = neighborsMatrixBounds.size.x;
            // Quantidade de colunas horizontais do Matrix.
            float boundsHeight = neighborsMatrixBounds.size.y;

            int boundsMaxX = neighborsMatrixBounds.xMax;
            int boundsMaxY = neighborsMatrixBounds.yMax;
            int boundsMinX = neighborsMatrixBounds.xMin;
            int boundsMinY = neighborsMatrixBounds.yMin;

            // Largura de cada coluna do Matrix.
            float matrixColumnWidth = matrixWidth / boundsWidth;
            // Altura de cada coluna do Matrix.
            float matrixColumnHeight = matrixHeight / boundsHeight;

            float matrixGUITop    = neighborsMatrixComponentRectangle.yMin;
            float matrixGUIRight  = neighborsMatrixComponentRectangle.xMax;
            float matrixGUIBottom = neighborsMatrixComponentRectangle.yMax;
            float matrixGUILeft   = neighborsMatrixComponentRectangle.xMin;

            // Draw horizontal columns.
            for (int horizontalColumnIndex = 0; horizontalColumnIndex <= boundsHeight; horizontalColumnIndex++)
            {
                float columnHeight = matrixGUITop + horizontalColumnIndex * matrixColumnHeight;

                Vector3 startPoint = new Vector3(matrixGUILeft, columnHeight);
                Vector3 endPoint   = new Vector3(matrixGUIRight, columnHeight);

                Handles.DrawLine(startPoint, endPoint);
            }

            // Draw vertical columns.
            for (int verticalColumnIndex = 0; verticalColumnIndex <= boundsWidth; verticalColumnIndex++)
            {
                float columnWidth = matrixGUILeft + verticalColumnIndex * matrixColumnWidth;

                Vector3 startPoint = new Vector3(columnWidth, matrixGUITop);
                Vector3 endPoint   = new Vector3(columnWidth, matrixGUIBottom);

                Handles.DrawLine(startPoint, endPoint);
            }

            Handles.color = Color.white;

            Dictionary <Vector3Int, int> neighbors = rule.GetNeighbors();

            // In a NeighborBox.
            for (int neighborY = boundsMinY; neighborY < boundsMaxX; neighborY++)
            {
                for (int neighborX = boundsMinX; neighborX < boundsMaxY; neighborX++)
                {
                    Vector3Int neighborBoxPositionOnMatrix = new Vector3Int(neighborX, neighborY, 0);

                    float neighborBoxPositionX = matrixGUILeft + (neighborX - boundsMinX) * matrixColumnWidth;
                    float neighborBoxPositionY = matrixGUITop + (-neighborY + boundsMaxY - 1) * matrixColumnHeight;
                    float width  = matrixColumnWidth - 1;
                    float height = matrixColumnHeight - 1;

                    Rect neighborBoxRectangle = new Rect(
                        neighborBoxPositionX,
                        neighborBoxPositionY,
                        width,
                        height
                        );

                    InNeighborBox(neighborBoxPositionOnMatrix, neighborBoxRectangle, rule, neighbors);
                }
            }
        }
예제 #9
0
        private void DrawTileDataComponent(Rect tileDataComponentRectangle, ScriptedTile.Rule rule)
        {
            float componentPositionX = tileDataComponentRectangle.x;
            float fieldPositionY     = tileDataComponentRectangle.y;
            Rect  fieldRectangle;

            /*
             * Inicia o `fieldOrderNumber`.
             * Ele controla a quantidade de padding que cada Field precisa.
             * A quantidade de padding é baseada na ordem (1º, 2º, ...) do Field.
             */
            int fieldOrderNumber = UpdateFieldOrderNumber(0);

            fieldRectangle      = GetFieldRectangle("Game Object", componentPositionX, ref fieldPositionY, ref fieldOrderNumber, tileDataComponentRectangle, rule);
            rule.tileGameObject = EditorGUI.ObjectField(fieldRectangle, "", rule.tileGameObject, typeof(GameObject), false) as GameObject;

            fieldRectangle        = GetFieldRectangle("Collider Type", componentPositionX, ref fieldPositionY, ref fieldOrderNumber, tileDataComponentRectangle, rule);
            rule.tileColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(fieldRectangle, rule.tileColliderType);

            fieldRectangle        = GetFieldRectangle("Sprite Output", componentPositionX, ref fieldPositionY, ref fieldOrderNumber, tileDataComponentRectangle, rule);
            rule.spriteOutputType = (ScriptedTile.RuleTileData.SpriteOutputType)EditorGUI.EnumPopup(fieldRectangle, rule.spriteOutputType);

            if (rule.spriteOutputType == ScriptedTile.RuleTileData.SpriteOutputType.Animation)
            {
                fieldRectangle      = GetFieldRectangle("Speed", componentPositionX, ref fieldPositionY, ref fieldOrderNumber, tileDataComponentRectangle, rule);
                rule.animationSpeed = EditorGUI.FloatField(fieldRectangle, rule.animationSpeed);
            }

            if (rule.spriteOutputType == ScriptedTile.RuleTileData.SpriteOutputType.Random)
            {
                fieldRectangle        = GetFieldRectangle("Noise", componentPositionX, ref fieldPositionY, ref fieldOrderNumber, tileDataComponentRectangle, rule);
                rule.perlinNoiseScale = EditorGUI.Slider(fieldRectangle, rule.perlinNoiseScale, 0.001f, 0.999f);

                fieldRectangle = GetFieldRectangle("Rotation", componentPositionX, ref fieldPositionY, ref fieldOrderNumber, tileDataComponentRectangle, rule);
                rule.randomSpriteRotationType = (ScriptedTile.Rule.RotationType)EditorGUI.EnumPopup(fieldRectangle, rule.randomSpriteRotationType);
            }

            // Lista de Sprites para a animação ou, para a randomização.
            if (rule.spriteOutputType != ScriptedTile.RuleTileData.SpriteOutputType.Single)
            {
                #region Sprites Fields.
                Rect spritesNumberLabelRectangle = new Rect(
                    componentPositionX,
                    fieldPositionY + GetFieldPaddingTopByFieldPositionY(fieldPositionY, fieldOrderNumber),
                    ReorderableListGUIDefaults.FieldWidth,
                    ReorderableListGUIDefaults.FieldHeight
                    );

                Rect spritesNumberFieldRectangle = new Rect(
                    componentPositionX + ReorderableListGUIDefaults.FieldWidth,
                    fieldPositionY + GetFieldPaddingTopByFieldPositionY(fieldPositionY, fieldOrderNumber),

                    /*
                     * `componentRectangle.width`: A largura do Field é proporcional a largura do element do ReorderableList,
                     * pois, `componentRectangle` é baseado no elementRectangle.
                     */
                    tileDataComponentRectangle.width - ReorderableListGUIDefaults.FieldWidth,
                    ReorderableListGUIDefaults.FieldHeight
                    );

                EditorGUI.BeginChangeCheck();

                GUI.Label(spritesNumberLabelRectangle, "Sprites");
                int spritesNumber = EditorGUI.DelayedIntField(spritesNumberFieldRectangle, rule.tileSprites.Length);

                /*
                 * Não há necessidade de ter mais que 500 Sprites por Rule.
                 * Um valor muito grande pode causar atrasos no Editor, por causa da quantidade de loops.
                 */
                spritesNumber = Mathf.Min(500, spritesNumber);

                // Modificar a lista de Sprites quando o Field acima (a quantidade de Sprites) for modificado.
                if (EditorGUI.EndChangeCheck())
                {
                    // Deve ter pelo menos um campo.
                    Array.Resize(ref rule.tileSprites, Mathf.Max(spritesNumber, 1));
                }

                fieldPositionY   = UpdateFieldPositionY(fieldPositionY);
                fieldOrderNumber = UpdateFieldOrderNumber(fieldOrderNumber);

                for (int spriteIndex = 0; spriteIndex < rule.tileSprites.Length; spriteIndex++)
                {
                    Rect spriteFieldRectangle = new Rect(
                        componentPositionX + ReorderableListGUIDefaults.FieldWidth,
                        fieldPositionY + GetFieldPaddingTopByFieldPositionY(fieldPositionY, fieldOrderNumber),

                        /*
                         * `componentRectangle.width`: A largura do Field é proporcional a largura do element do ReorderableList,
                         * pois, `componentRectangle` é baseado no elementRectangle.
                         */
                        tileDataComponentRectangle.width - ReorderableListGUIDefaults.FieldWidth,
                        ReorderableListGUIDefaults.FieldHeight
                        );

                    rule.tileSprites[spriteIndex] = EditorGUI.ObjectField(spriteFieldRectangle, rule.tileSprites[spriteIndex], typeof(Sprite), false) as Sprite;

                    fieldPositionY   = UpdateFieldPositionY(fieldPositionY);
                    fieldOrderNumber = UpdateFieldOrderNumber(fieldOrderNumber);
                }
                #endregion
            }
        }
예제 #10
0
        private void OnDrawRLElement(Rect elementRectangle, int ruleIndex, bool isActive, bool isFocused)
        {
            ScriptedTile.Rule rule = scriptedTile.rules[ruleIndex];

            float elementGUITop   = elementRectangle.yMin;
            float elementGUIRight = elementRectangle.xMax;
            float elementGUILeft  = elementRectangle.xMin;

            BoundsInt neighborsMatrixBounds = GetNeighborsMatrixBounds(rule.GetNeighborsMatrixBoundsBySelectedNeighbors());
            Vector2   neighborsMatrixGUI    = TransformNeighborsMatrixBoundsToGUI(neighborsMatrixBounds);

            float neighborsMatrixGUIWidth  = neighborsMatrixGUI.x;
            float neighborsMatrixGUIHeight = neighborsMatrixGUI.y;

            #region SpriteComponent Rectangle.
            float spriteComponentPositionX = elementGUIRight - ReorderableListGUIDefaults.ComponentWidth;
            float spriteComponentPositionY = elementGUITop + ReorderableListGUIDefaults.FieldPaddingTop * 2;
            float spriteComponentWidth     = ReorderableListGUIDefaults.ComponentWidth;
            float spriteComponentHeight    = ReorderableListGUIDefaults.ElementHeight;

            // Separar o espaço deste componente dentro do element do ReorderableList.
            Rect spriteComponentRectangle = new Rect(
                spriteComponentPositionX,
                spriteComponentPositionY,
                spriteComponentWidth,
                spriteComponentHeight
                );
            #endregion

            #region NeighborsMatrixComponent Rectangle.
            float neighborsMatrixComponentPositionX = elementGUIRight - neighborsMatrixGUIWidth - spriteComponentWidth - 10f;
            float neighborsMatrixComponentPositionY = elementGUITop + ReorderableListGUIDefaults.FieldPaddingTop * 2;
            float neighborsMatrixComponentWidth     = neighborsMatrixGUIWidth;
            float neighborsMatrixComponentHeight    = neighborsMatrixGUIHeight;

            // Separar o espaço deste componente dentro do element do ReorderableList.
            Rect neighborsMatrixComponentRectangle = new Rect(
                neighborsMatrixComponentPositionX,
                neighborsMatrixComponentPositionY,
                neighborsMatrixComponentWidth,
                neighborsMatrixComponentHeight
                );
            #endregion

            #region TileDataComponent Rectangle.
            float tileDataComponentPositionX = elementGUILeft;
            float tileDataComponentPositionY = elementGUITop + ReorderableListGUIDefaults.FieldPaddingTop;
            float tileDataComponentWidth     = elementRectangle.width - neighborsMatrixGUIWidth - spriteComponentRectangle.width - 20f;
            float tileDataComponentHeight    = elementRectangle.height - ReorderableListGUIDefaults.ElementPaddingHeight;

            // Separar o espaço deste componente dentro do element do ReorderableList.
            Rect tileDataComponentRectangle = new Rect(
                tileDataComponentPositionX,
                tileDataComponentPositionY,
                tileDataComponentWidth,
                tileDataComponentHeight
                );
            #endregion

            DrawTileDataComponent(tileDataComponentRectangle, rule);
            DrawNeighborsMatrixComponent(neighborsMatrixComponentRectangle, neighborsMatrixBounds, scriptedTile, rule);
            DrawSpriteComponent(spriteComponentRectangle, rule);
        }