private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused)
        {
            TilingRule rule = this.tile.TilingRules[index];

            float yPos        = rect.yMin + 2f;
            float height      = rect.height - PaddingBetweenRules;
            float matrixWidth = DefaultElementHeight;

            Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
            Rect matrixRect    = new Rect(rect.xMax - matrixWidth * 2f - 10f, yPos, matrixWidth, DefaultElementHeight);
            Rect spriteRect    = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, DefaultElementHeight);

            EditorGUI.BeginChangeCheck();
            RuleInspectorOnGUI(inspectorRect, rule);
            RuleMatrixOnGUI(matrixRect, rule);
            SpriteOnGUI(spriteRect, rule);
            if (EditorGUI.EndChangeCheck())
            {
                SaveTile();
            }
        }
 public bool RuleMatches(TilingRule rule, Vector3Int position, ITilemap tilemap, int angle)
 {
     for (int y = -1; y <= 1; y++)
     {
         for (int x = -1; x <= 1; x++)
         {
             if (x != 0 ||
                 y != 0)
             {
                 Vector3Int offset  = new Vector3Int(x, y, 0);
                 Vector3Int rotated = GetRotatedPos(offset, angle);
                 int        index   = GetIndexOfOffset(rotated);
                 TileBase   tile    = tilemap.GetTile(position + offset);
                 if (rule.m_Neighbors[index] == TilingRule.Neighbor.This && tile != this ||
                     rule.m_Neighbors[index] == TilingRule.Neighbor.NotThis && tile == this)
                 {
                     return(false);
                 }
             }
         }
     }
     return(true);
 }
 public MenuItemData(TilingRule mRule, TilingRule.Transform mNewValue)
 {
     this.m_Rule     = mRule;
     this.m_NewValue = mNewValue;
 }
        private static void RuleMatrixOnGUI(Rect rect, TilingRule tilingRule)
        {
            Handles.color = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.2f) : new Color(0f, 0f, 0f, 0.2f);
            int   index = 0;
            float w     = rect.width / 3f;
            float h     = rect.height / 3f;

            for (int y = 0; y <= 3; y++)
            {
                float top = rect.yMin + y * h;
                Handles.DrawLine(new Vector3(rect.xMin, top), new Vector3(rect.xMax, top));
            }
            for (int x = 0; x <= 3; x++)
            {
                float left = rect.xMin + x * w;
                Handles.DrawLine(new Vector3(left, rect.yMin), new Vector3(left, rect.yMax));
            }
            Handles.color = Color.white;

            for (int y = 0; y <= 2; y++)
            {
                for (int x = 0; x <= 2; x++)
                {
                    Rect r = new Rect(rect.xMin + x * w, rect.yMin + y * h, w - 1, h - 1);
                    if (x != 1 ||
                        y != 1)
                    {
                        switch (tilingRule.m_Neighbors[index])
                        {
                        case TilingRule.Neighbor.This:
                            GUI.DrawTexture(r, Arrows[y * 3 + x]);
                            break;

                        case TilingRule.Neighbor.NotThis:
                            GUI.DrawTexture(r, Arrows[9]);
                            break;
                        }
                        if (Event.current.type == EventType.MouseDown &&
                            r.Contains(Event.current.mousePosition))
                        {
                            tilingRule.m_Neighbors[index] = (TilingRule.Neighbor)(((int)tilingRule.m_Neighbors[index] + 1) % 3);
                            GUI.changed = true;
                            Event.current.Use();
                        }

                        index++;
                    }
                    else
                    {
                        switch (tilingRule.m_RuleTransform)
                        {
                        case TilingRule.Transform.Rotated:
                            GUI.DrawTexture(r, AutoTransforms[0]);
                            break;

                        case TilingRule.Transform.MirrorX:
                            GUI.DrawTexture(r, AutoTransforms[1]);
                            break;

                        case TilingRule.Transform.MirrorY:
                            GUI.DrawTexture(r, AutoTransforms[2]);
                            break;
                        }

                        if (Event.current.type == EventType.MouseDown &&
                            r.Contains(Event.current.mousePosition))
                        {
                            tilingRule.m_RuleTransform = (TilingRule.Transform)(((int)tilingRule.m_RuleTransform + 1) % 4);
                            GUI.changed = true;
                            Event.current.Use();
                        }
                    }
                }
            }
        }
        private static void RuleInspectorOnGUI(Rect rect, TilingRule tilingRule)
        {
            float y = rect.yMin;

            EditorGUI.BeginChangeCheck();
            GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Rule");
            tilingRule.m_RuleTransform =
                (TilingRule.Transform)
                EditorGUI.EnumPopup(
                    new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                    tilingRule.m_RuleTransform);
            y += SingleLineHeight;
            GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Collider");
            tilingRule.m_ColliderType =
                (Tile.ColliderType)
                EditorGUI.EnumPopup(
                    new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                    tilingRule.m_ColliderType);
            y += SingleLineHeight;
            GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Output");
            tilingRule.m_Output =
                (TilingRule.OutputSprite)
                EditorGUI.EnumPopup(
                    new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                    tilingRule.m_Output);
            y += SingleLineHeight;

            if (tilingRule.m_Output == TilingRule.OutputSprite.Animation)
            {
                GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Speed");
                tilingRule.m_AnimationSpeed =
                    EditorGUI.FloatField(
                        new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                        tilingRule.m_AnimationSpeed);
                y += SingleLineHeight;
            }
            if (tilingRule.m_Output == TilingRule.OutputSprite.Random)
            {
                GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Noise");
                tilingRule.m_PerlinScale =
                    EditorGUI.Slider(
                        new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                        tilingRule.m_PerlinScale,
                        0.001f,
                        0.999f);
                y += SingleLineHeight;

                GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Shuffle");
                tilingRule.m_RandomTransform =
                    (TilingRule.Transform)
                    EditorGUI.EnumPopup(
                        new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                        tilingRule.m_RandomTransform);
                y += SingleLineHeight;
            }

            if (tilingRule.m_Output != TilingRule.OutputSprite.Single)
            {
                GUI.Label(new Rect(rect.xMin, y, LabelWidth, SingleLineHeight), "Size");
                EditorGUI.BeginChangeCheck();
                int newLength =
                    EditorGUI.DelayedIntField(
                        new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                        tilingRule.m_Sprites.Length);
                if (EditorGUI.EndChangeCheck())
                {
                    Array.Resize(ref tilingRule.m_Sprites, Math.Max(newLength, 1));
                }
                y += SingleLineHeight;

                for (int i = 0; i < tilingRule.m_Sprites.Length; i++)
                {
                    tilingRule.m_Sprites[i] =
                        EditorGUI.ObjectField(
                            new Rect(rect.xMin + LabelWidth, y, rect.width - LabelWidth, SingleLineHeight),
                            tilingRule.m_Sprites[i],
                            typeof(Sprite),
                            false) as Sprite;
                    y += SingleLineHeight;
                }
            }
        }