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(); } }
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); }
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(); } }
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)); }
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); }
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); } } }
private void DrawSpriteComponent(Rect spriteComponentRectangle, ScriptedTile.Rule rule) { rule.tileSprites[0] = EditorGUI.ObjectField(spriteComponentRectangle, rule.tileSprites[0], typeof(Sprite), false) as Sprite; }
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); } } }
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 } }
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); }