Esempio n. 1
0
 private void handlePickRequest()
 {
     if (state == PickerState.empty)
     {
         var pickedup = PlacementLogic.handlePickUpRequest(transform.position);
         if (pickedup != null)
         {
             state  = PickerState.full;
             picked = Transform.Instantiate(pickedup.getGameObject().transform, new Vector3(-1000, -1000, -1000), pickedup.getGameObject().transform.rotation, transform);
             if (pickedup.model != null)
             {
                 pickedModel = Transform.Instantiate <Transform>(pickedup.model, transform.position, pickedup.getGameObject().transform.rotation, transform);
                 pickedModel.gameObject.SetActive(true);
             }
             Destroy(pickedup.getGameObject());
         }
     }
     else if (state == PickerState.full)
     {
         var placed = PlacementLogic.handlePlaceRequest(picked, transform.position);
         if (placed)
         {
             state = PickerState.empty;
             picked.GetComponent <Syncable>().Delete();
             placed.gameObject.SetActive(true);
             if (pickedModel != null)
             {
                 Destroy(pickedModel.gameObject);
             }
             transform.rotation = Quaternion.identity;
         }
     }
 }
    internal override bool MouseMoved(IGameViewport viewport, MessageMouseArgs args)
    {
        ClearResults();
        PickerStatusFlags |= PickerStatusFlags.Invalid;

        var raycastFlags = PickerState.GetFlagsFromExclusions();

        GameSystems.Raycast.PickObjectOnScreen(viewport, args.X, args.Y, out var target, raycastFlags);

        PickerState.Target = target;
        if (target != Picker.caster)
        {
            return(false);
        }

        PickerStatusFlags &= ~PickerStatusFlags.Invalid;

        if (!Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Radius))
        {
            Picker.SetSingleTgt(target);
        }
        else
        {
            Picker.SetAreaTargets(target.GetLocationFull());
        }

        return(false);
    }
Esempio n. 3
0
 /// <summary>
 /// Shows the picker window.
 /// </summary>
 /// <param name="state">State.</param>
 /// <param name="filter">Filter.</param>
 private void ShowPicker <T>(PickerState state, string filter) where T : UnityEngine.Object
 {
     pickerState = state;
     // Create a window picker control ID
     currentPickerWindow = EditorGUIUtility.GetControlID(FocusType.Passive);
     // Use the ID you just created
     EditorGUIUtility.ShowObjectPicker <T>(null, false, filter, currentPickerWindow);
 }
Esempio n. 4
0
 public SingleTargetBehavior(PickerState pickerState) : base(pickerState)
 {
     UiSystems.Party.SetTargetCallbacks(
         SelectSingleTargetCallback,
         PickerMultiSingleCheckFlags,
         ActivePickerReset
         );
 }
Esempio n. 5
0
    /// <summary>
    /// Display level description GUI.
    /// </summary>
    private void LevelDescriptionGUI()
    {
        if (myState == MyState.LevelDescription && mySubState.Contains(MySubState.LevelDescription))
        {
            GUILayout.Space(guiSpace);

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            // Set level icon button
            if (GUILayout.Button(contents.levelIcon, GUILayout.MaxWidth(100f), GUILayout.MaxHeight(100f)) == true)
            {
                ShowPicker(PickerState.LevelIcon, Lables.levelIcon);
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
            // Header
            GUILayout.Label("Header");
            inspectors.levelDescription.header.text = EditorGUILayout.TextField(inspectors.levelDescription.header.text);
            // Description
            GUILayout.Label("Description");
            inspectors.levelDescription.description.text = EditorGUILayout.TextArea(inspectors.levelDescription.description.text, GUILayout.MaxHeight(80f));
            // Attention
            GUILayout.Label("Attention");
            inspectors.levelDescription.attention.text = EditorGUILayout.TextArea(inspectors.levelDescription.attention.text, GUILayout.MaxHeight(40f));

            // New object selected in picker window
            if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                pickedGameObject = EditorGUIUtility.GetObjectPickerObject() as GameObject;
                if (pickedGameObject != null)
                {
                    SpriteRenderer spriteRenderer = pickedGameObject.GetComponent <SpriteRenderer>();
                    if (spriteRenderer != null)
                    {
                        // Set icon in level description
                        inspectors.levelDescription.icon.sprite = spriteRenderer.sprite;
                        EditorUtility.SetDirty(inspectors.levelDescription.gameObject);
                        contents.levelIcon = new GUIContent(inspectors.levelDescription.icon.sprite.texture, "Choose icon for this level");
                    }
                }
            }
            // Picker window closed
            if (Event.current.commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                pickedGameObject = null;
                pickerState      = PickerState.None;
            }

            if (GUI.changed == true)
            {
                EditorUtility.SetDirty(inspectors.levelDescription.gameObject);
            }
        }
    }
    internal override bool MouseMoved(IGameViewport viewport, MessageMouseArgs args)
    {
        PickerStatusFlags &= ~PickerStatusFlags.Invalid;

        if (HandleClickInUnexploredArea(args.X, args.Y))
        {
            return(false);
        }

        // The picker may allow picking an object directly (which will be the basis of the area effect)
        if (Picker.modeTarget.HasFlag(UiPickerType.AreaOrObj))
        {
            var flags = PickerState.GetFlagsFromExclusions();
            if (GameSystems.Raycast.PickObjectOnScreen(viewport, args.X, args.Y, out var target, flags))
            {
                if ((Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.LosNotRequired) || !Picker.LosBlocked(target)) &&
                    Picker.CheckTargetVsIncFlags(target) &&
                    Picker.TargetValid(target))
                {
                    ClearResults();
                    Picker.SetAreaTargets(target.GetLocationFull());
                    Result.flags |= PickerResultFlags.PRF_HAS_SELECTED_OBJECT;

                    // Sort the primary focus of selection to the beginning of the list,
                    // But don't insert it if it isn't in the list already
                    if (Result.objList.Remove(target))
                    {
                        Result.objList.Insert(0, target);
                    }

                    return(false);
                }
            }
        }

        var targetLoc = GameViews.Primary.ScreenToTile(args.X, args.Y);

        // Even when the picked object above is not valid, targeting the location underneath is a valid alternative
        if (!Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.LosNotRequired) &&
            !HasLineOfSight(Picker.caster, targetLoc))
        {
            ClearResults();
            PickerStatusFlags |= PickerStatusFlags.Invalid;
            return(false);
        }

        Picker.SetAreaTargets(targetLoc);
        return(false);
    }
Esempio n. 7
0
    internal override bool MouseMoved(IGameViewport viewport, MessageMouseArgs args)
    {
        if (HandleClickInUnexploredArea(args.X, args.Y))
        {
            return(false);
        }

        var raycastFlags = PickerState.GetFlagsFromExclusions();

        if (!GameSystems.Raycast.PickObjectOnScreen(viewport, args.X, args.Y, out var target, raycastFlags))
        {
            PickerStatusFlags &= ~(PickerStatusFlags.Invalid | PickerStatusFlags.OutOfRange);
            PickerState.Target = null;
            return(true);
        }

        PickerState.Target = target;

        if (Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Exclude1st))
        {
            if (!Picker.TargetValid(target))
            {
                PickerStatusFlags |= PickerStatusFlags.Invalid;
            }
        }

        if (!Picker.CheckTargetVsIncFlags(target))
        {
            PickerStatusFlags |= PickerStatusFlags.Invalid;
        }

        if (!Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.LosNotRequired) && Picker.LosBlocked(target))
        {
            PickerStatusFlags |= PickerStatusFlags.Invalid;
        }

        if (Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Range))
        {
            // TODO: This distance check seems bugged too (feet vs. inch, no radius considered)
            var dist = Picker.caster.GetLocationFull().DistanceTo(target.GetLocationFull());

            if (dist > Picker.range)
            {
                PickerStatusFlags |= PickerStatusFlags.OutOfRange;
            }
        }

        return(true);
    }
Esempio n. 8
0
    /// <summary>
    /// Display building place GUI.
    /// </summary>
    private void BuildingPlaceGUI()
    {
        if (myState == MyState.LevelMap && mySubState.Contains(MySubState.BuildingPlace))
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Tower");
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            // Focus on building place button
            if (GUILayout.Button(contents.buildingPlace, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)) == true)
            {
                Selection.activeObject = inspectors.buildingPlace.gameObject;
            }
            // Focus on defend point button
            if (GUILayout.Button(contents.defendPoint, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)) == true)
            {
                Selection.activeObject = inspectors.buildingPlace.GetDefendPoint();
            }
            // Change tower button
            if (GUILayout.Button(contents.tower, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)) == true)
            {
                ShowPicker(PickerState.Tower, Lables.tower);
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            // New object selected in picker window
            if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                pickedGameObject = EditorGUIUtility.GetObjectPickerObject() as GameObject;
                if (pickedGameObject != null)
                {
                    // Set new tower for this building place
                    Selection.activeObject = inspectors.buildingPlace.ChooseTower(pickedGameObject);
                }
            }
            // Picker window closed
            if (Event.current.commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                pickedGameObject = null;
                pickerState      = PickerState.None;
            }
        }
    }
Esempio n. 9
0
    internal override bool LeftMouseButtonReleased(IGameViewport viewport, MessageMouseArgs args)
    {
        if (HandleClickInUnexploredArea(args.X, args.Y))
        {
            return(false);
        }

        ClearResults();

        var raycastFlags = PickerState.GetFlagsFromExclusions();

        if (!GameSystems.Raycast.PickObjectOnScreen(viewport, args.X, args.Y, out var objFound, raycastFlags))
        {
            return(false);
        }

        if (!PickerState.Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.LosNotRequired) &&
            PickerState.Picker.LosBlocked(objFound))
        {
            return(false);
        }

        if (PickerState.Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Exclude1st) &&
            !PickerState.Picker.TargetValid(objFound))
        {
            return(false);
        }

        if (!PickerState.Picker.CheckTargetVsIncFlags(objFound))
        {
            return(false);
        }

        Result.flags  = PickerResultFlags.PRF_HAS_SINGLE_OBJ;
        Result.handle = objFound;
        SetResultLocation(objFound);

        return(FinalizePicker());
    }
    internal override bool LeftMouseButtonReleased(IGameViewport viewport, MessageMouseArgs args)
    {
        ClearResults();

        var raycastFlags = PickerState.GetFlagsFromExclusions();

        if (!GameSystems.Raycast.PickObjectOnScreen(viewport, args.X, args.Y, out var target, raycastFlags) ||
            target != Picker.caster)
        {
            return(true);
        }

        if (!Picker.flagsTarget.HasFlag(UiPickerFlagsTarget.Radius))
        {
            Picker.SetSingleTgt(target);
        }
        else
        {
            Picker.SetAreaTargets(target.GetLocationFull());
        }

        return(FinalizePicker());
    }
 public AreaTargetBehavior(PickerState pickerState) : base(pickerState)
 {
     UiSystems.Party.SetTargetCallbacks(TargetPartyMember, SetPartyMemberTarget, ResetPartyMemberTarget);
 }
Esempio n. 12
0
 public InventoryItemTargetBehavior(PickerState pickerState) : base(pickerState)
 {
     UiSystems.CharSheet.ShowItemPicker(Picker.caster, SelectSingleTargetCallback);
 }
Esempio n. 13
0
    /// <summary>
    /// Raises the GU event.
    /// </summary>
    void OnGUI()
    {
        GUI.skin = null;

        if (EditorApplication.isPlaying == false)
        {
            GUILayout.Space(5);

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUI.skin = myState == MyStates.Pointer ? null : tilesGuiSkin;
            if (GUILayout.Button(contents.pointer) == true)
            {
                myState = MyStates.Pointer;
                UpdateTemp();
                tileIdx        = -1;
                environmentIdx = -1;
            }
            GUI.skin = null;
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(20);

            if (GUILayout.Button("Choose background") == true)
            {
                ShowPicker <Sprite>(PickerState.Map, mapSpriteLabel);
            }

            GUI.skin = tilesGuiSkin;

            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("------------Environment------------");
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("In game sorting");
            inGameSorting = EditorGUILayout.Toggle(inGameSorting);
            EditorGUILayout.EndHorizontal();

            environmentScrollPos = EditorGUILayout.BeginScrollView(environmentScrollPos, GUILayout.MaxHeight(120));
            int environmentNewIdx = GUILayout.SelectionGrid(environmentIdx, environmentTextures, 4);
            if (environmentNewIdx != environmentIdx)
            {
                environmentIdx = environmentNewIdx;
                if (environmentIdx >= 0)
                {
                    myState = MyStates.EnvironmentPlacement;
                    UpdateTemp();
                    tileIdx = -1;
                    SetEnvironment(environmentPrefabs[environmentIdx]);
                }
            }
            EditorGUILayout.EndScrollView();

            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("---------------Tiles---------------");
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Snap step");
            snapStep = EditorGUILayout.FloatField(snapStep);
            EditorGUILayout.EndHorizontal();

            tilesScrollPos = EditorGUILayout.BeginScrollView(tilesScrollPos, GUILayout.MaxHeight(140));
            int tileNewIdx = GUILayout.SelectionGrid(tileIdx, tileTextures, 4);
            if (tileNewIdx != tileIdx)
            {
                tileIdx = tileNewIdx;
                if (tileIdx >= 0)
                {
                    myState = MyStates.TilePlacement;
                    UpdateTemp();
                    environmentIdx = -1;
                    SetTile(tilePrefabs[tileIdx]);
                }
            }
            EditorGUILayout.EndScrollView();

            GUI.skin = null;

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(contents.rotateLeft) == true)
            {
                RotateTile(90f);
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Button(contents.rotateRight) == true)
            {
                RotateTile(-90f);
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            if (myState == MyStates.Pointer)
            {
                GUILayout.Space(20);
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel("Map name");
                mapName = EditorGUILayout.TextField(mapName);
                EditorGUILayout.EndHorizontal();

                if (GUILayout.Button("Save map") == true)
                {
                    if (mapFolderInspector != null)
                    {
                        if (mapFolderInspector.map != null)
                        {
                            mapFolderInspector.map.gameObject.name = mapName;
                            GameObject newMapPrefab = PrefabUtility.CreatePrefab("Assets/TD2D/Prefabs/Map/LevelMaps/" + mapName + ".prefab", mapFolderInspector.map.gameObject, ReplacePrefabOptions.ConnectToPrefab);
                            AssetDatabase.Refresh();
                            Selection.activeObject = newMapPrefab;
                            EditorUtility.FocusProjectWindow();
                        }
                    }
                }
            }

            // New object selected in picker window
            if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                pickedObject = EditorGUIUtility.GetObjectPickerObject();
            }
            // Picker window closed
            if (Event.current.commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                switch (pickerState)
                {
                case PickerState.Map:
                    if (pickedObject != null && pickedObject is Sprite && mapFolderInspector != null)
                    {
                        mapFolderInspector.ChangeMapSprite(pickedObject as Sprite);
                        EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
                    }
                    break;
                }

                pickedObject = null;
                pickerState  = PickerState.None;
            }
        }
        else
        {
            EditorGUILayout.HelpBox("Editor disabled in play mode", MessageType.Info);
        }
    }
 protected PickerBehavior(PickerState pickerState)
 {
     PickerState = pickerState;
 }
Esempio n. 15
0
        // TODO: Change this to an Enum or something like that
        private void SetMode(PickerState state)
        {
            switch (state)
            {
                case PickerState.RGB:
                    SelectorCT.Visibility = Visibility.Collapsed;
                    SelectorRGB.Visibility = Visibility.Visible;
                    Brightness.Visibility = Visibility.Visible;

                    OptionRGB.Style = SelectorActive;
                    OptionCT.Style = SelectorInactive;
                    OptionOff.Style = SelectorInactive;
                    break;

                case PickerState.CT:
                    SelectorCT.Visibility = Visibility.Visible;
                    SelectorRGB.Visibility = Visibility.Collapsed;
                    Brightness.Visibility = Visibility.Visible;

                    OptionRGB.Style = SelectorInactive;
                    OptionCT.Style = SelectorActive;
                    OptionOff.Style = SelectorInactive;
                    break;

                case PickerState.Off:
                    SelectorCT.Visibility = Visibility.Collapsed;
                    SelectorRGB.Visibility = Visibility.Collapsed;
                    Brightness.Visibility = Visibility.Collapsed;

                    OptionRGB.Style = SelectorInactive;
                    OptionCT.Style = SelectorInactive;
                    OptionOff.Style = SelectorActive;
                    break;
            }
        }
 public LocationTargetBehavior(PickerState pickerState) : base(pickerState)
 {
 }
 public RayTargetBehavior(PickerState pickerState) : base(pickerState)
 {
 }
 public PersonalTargetBehavior(PickerState pickerState) : base(pickerState)
 {
 }
Esempio n. 19
0
    /// <summary>
    /// Display map GUI.
    /// </summary>
    private void MapGUI()
    {
        if (myState == MyState.LevelMap && mySubState.Contains(MySubState.MapFolder))
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Map");
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            // Choose map image button
            if (GUILayout.Button(contents.chooseMap, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)) == true)
            {
                ShowPicker(PickerState.Map, Lables.map);
            }
            // Create spawn icon button
            if (GUILayout.Button(contents.spawnIcon, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)) == true)
            {
                ShowPicker(PickerState.SpawnIcon, Lables.spawnIcon);
            }
            // Create capture icon button
            if (GUILayout.Button(contents.captureIcon, GUILayout.Width(buttonWidth), GUILayout.Height(buttonHeight)) == true)
            {
                ShowPicker(PickerState.CaptureIcon, Lables.captureIcon);
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            // New object selected in picker window
            if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                pickedGameObject = EditorGUIUtility.GetObjectPickerObject() as GameObject;

                switch (pickerState)
                {
                case PickerState.Map:
                    if (pickedGameObject != null)
                    {
                        // Change map image
                        Selection.activeObject = inspectors.mapFolder.ChangeMapSprite(pickedGameObject);
                    }
                    break;
                }
            }
            // Picker window closed
            if (Event.current.commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
            {
                switch (pickerState)
                {
                case PickerState.SpawnIcon:
                    if (pickedGameObject != null)
                    {
                        // Add spawn icon to map
                        Selection.activeObject = inspectors.mapFolder.AddSpawnIcon(pickedGameObject);
                    }
                    break;

                case PickerState.CaptureIcon:
                    if (pickedGameObject != null)
                    {
                        // Add capture icon to map
                        Selection.activeObject = inspectors.mapFolder.AddCaptureIcon(pickedGameObject);
                    }
                    break;
                }

                pickedGameObject = null;
                pickerState      = PickerState.None;
            }
        }
    }
 public WallTargetBehavior(PickerState pickerState) : base(pickerState)
 {
     WallState = WallState.StartPoint;
 }
Esempio n. 21
0
    /// <summary>
    /// Raises the GU event.
    /// </summary>
    void OnGUI()
    {
        // Set visual theme
        GUI.skin = editorGuiSkin;

        if (EditorApplication.isPlaying == false)
        {
            switch (myState)
            {
            case MyState.Disabled:

                EditorGUILayout.HelpBox("Create your own units and towers", MessageType.Info);

                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                // Add new enemy button
                if (GUILayout.Button(contents.newEnemyButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true)
                {
                    CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Enemy", "Assets/TD2D/Prefabs/Units/Enemies/Units/Enemy");
                }
                // Add new defender button
                if (GUILayout.Button(contents.newDefenderButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true)
                {
                    CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Defender", "Assets/TD2D/Prefabs/Units/Defenders/Defender");
                }
                // Add new ranged tower button
                if (GUILayout.Button(contents.newTowerButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true)
                {
                    CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Tower", "Assets/TD2D/Prefabs/Units/Towers/Towers/MyTowers/Tower");
                }
                // Add new barracks button
                if (GUILayout.Button(contents.newBarracksButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true)
                {
                    CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Barracks", "Assets/TD2D/Prefabs/Units/Towers/Towers/MyTowers/Barracks");
                }
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
                break;

            case MyState.Enemy:
            case MyState.Defender:
            case MyState.Tower:
            case MyState.Barracks:

                GUILayout.Space(guiSpace);

                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                GUILayout.Label(unitData.gameObject.name);
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();

                if (myState == MyState.Enemy || myState == MyState.Tower || myState == MyState.Barracks)
                {
                    // Price
                    if (unitData.price != null)
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Price");
                        unitData.price.price = EditorGUILayout.IntField(unitData.price.price);
                        EditorGUILayout.EndHorizontal();

                        GUILayout.Space(guiSpace);
                    }
                }

                if (myState == MyState.Enemy || myState == MyState.Defender)
                {
                    // Speed
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.PrefixLabel("Speed");
                    unitData.navAgent.speed = EditorGUILayout.FloatField(unitData.navAgent.speed);
                    EditorGUILayout.EndHorizontal();

                    // Hitpoints
                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.PrefixLabel("Hitpoints");
                    unitData.damageTaker.hitpoints = EditorGUILayout.IntField(unitData.damageTaker.hitpoints);
                    EditorGUILayout.EndHorizontal();
                }

                if (myState == MyState.Enemy)
                {
                    // Flying flag
                    bool flyingEnemy = EditorGUILayout.Toggle("Flying", unitData.flying);
                    if (flyingEnemy != unitData.flying && unitData.gameObject != null)
                    {
                        unitData.gameObject.tag = flyingEnemy == true ? "FlyingEnemy" : "Enemy";
                        unitData.flying         = flyingEnemy;
                    }
                }

                if (myState == MyState.Enemy || myState == MyState.Defender || myState == MyState.Tower)
                {
                    GUILayout.Space(guiSpace);

                    EditorGUILayout.BeginHorizontal();
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Attack");
                    GUILayout.FlexibleSpace();
                    EditorGUILayout.EndHorizontal();
                }

                if (myState == MyState.Enemy || myState == MyState.Defender)
                {
                    // Attack type
                    string[] attackTypes = new string[] { "None", "Melee", "Ranged" };
                    int      attackType  = GUILayout.SelectionGrid(unitData.attackType, attackTypes, 1, EditorStyles.radioButton);
                    if (attackType != unitData.attackType)
                    {
                        if (unitData.attack != null)
                        {
                            DestroyImmediate(unitData.attack.gameObject);
                            unitData.attack = null;
                        }
                        switch (attackType)
                        {
                        case 1:
                            Object meleeAttackPrefab = AssetDatabase.LoadAssetAtPath <Object>("Assets/TD2D/Prefabs/Stuff/AttackTypes/MeleeAttack.prefab");
                            if (meleeAttackPrefab != null)
                            {
                                GameObject meleeAttack = Instantiate(meleeAttackPrefab, unitData.gameObject.transform) as GameObject;
                                meleeAttack.name = meleeAttackPrefab.name;
                                unitData.attack  = meleeAttack.GetComponent <Attack>();
                            }
                            break;

                        case 2:
                            Object rangedAttackPrefab = AssetDatabase.LoadAssetAtPath <Object>("Assets/TD2D/Prefabs/Stuff/AttackTypes/RangedAttack.prefab");
                            if (rangedAttackPrefab != null)
                            {
                                GameObject rangedAttack = Instantiate(rangedAttackPrefab, unitData.gameObject.transform) as GameObject;
                                rangedAttack.name = rangedAttackPrefab.name;
                                unitData.attack   = rangedAttack.GetComponent <Attack>();
                            }
                            break;
                        }
                        unitData.attackType    = attackType;
                        Selection.activeObject = unitData.gameObject.gameObject;
                        UpdateLayersAndTags();
                    }
                }

                if (myState == MyState.Enemy || myState == MyState.Defender || myState == MyState.Tower)
                {
                    if (unitData.attack != null)
                    {
                        // Damage
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Damage");
                        unitData.attack.damage = EditorGUILayout.IntField(unitData.attack.damage);
                        EditorGUILayout.EndHorizontal();
                        // Cooldown
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Cooldown");
                        unitData.attack.cooldown = EditorGUILayout.FloatField(unitData.attack.cooldown);
                        EditorGUILayout.EndHorizontal();
                        // Range
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Range");
                        unitData.attack.transform.localScale = EditorGUILayout.FloatField(unitData.attack.transform.localScale.x) * Vector3.one;
                        EditorGUILayout.EndHorizontal();
                    }

                    if (unitData.attack is AttackRanged)
                    {
                        // Choose bullet button
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button(contents.chooseBulletButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true)
                        {
                            switch (unitData.gameObject.tag)
                            {
                            case "Defender":
                            case "Tower":
                                ShowPicker <GameObject>(PickerState.BulletAlly, Lables.bulletAlly);
                                break;

                            case "Enemy":
                            case "FlyingEnemy":
                                ShowPicker <GameObject>(PickerState.BulletEnemy, Lables.bulletEnemy);
                                break;
                            }
                        }
                        // Focus on firepoint button
                        if (GUILayout.Button(contents.focusOnFirePointButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true)
                        {
                            if ((unitData.attack as AttackRanged).firePoint != null)
                            {
                                Selection.activeGameObject = (unitData.attack as AttackRanged).firePoint.gameObject;
                            }
                        }
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();
                    }
                }

                if (myState == MyState.Enemy)
                {
                    if (unitData.aiFeature != null)
                    {
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        GUILayout.Label("Features");
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();

                        AiFeature feature = (Selection.activeObject as GameObject).GetComponent <AiFeature>();

                        // Features buttons
                        EditorGUILayout.BeginHorizontal();
                        if (GUILayout.Button(contents.add, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                        {
                            ShowPicker <GameObject>(PickerState.Features, Lables.feature);
                        }
                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button(contents.prev, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                        {
                            Selection.activeObject = unitData.aiFeature.GetPreviousFeature(Selection.activeObject as GameObject);
                        }
                        if (GUILayout.Button(contents.next, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                        {
                            Selection.activeObject = unitData.aiFeature.GetNextFeature(Selection.activeObject as GameObject);
                        }
                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button(contents.remove, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                        {
                            if (feature != null)
                            {
                                DestroyImmediate(feature.gameObject);
                                Selection.activeObject = unitData.gameObject;
                            }
                        }
                        EditorGUILayout.EndHorizontal();

                        if (feature != null)
                        {
                            EditorGUILayout.BeginHorizontal();
                            GUILayout.FlexibleSpace();
                            GUILayout.Label(feature.name);
                            GUILayout.FlexibleSpace();
                            EditorGUILayout.EndHorizontal();

                            AiFeaturesGUI(feature);
                        }
                    }
                }

                if (myState == MyState.Defender || myState == MyState.Tower)
                {
                    if (unitData.attack != null)
                    {
                        // Targets
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        GUILayout.Label("Targets");
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();

                        bool land   = EditorGUILayout.Toggle("Land", unitData.targetCommon);
                        bool flying = EditorGUILayout.Toggle("Flying", unitData.targetFlying);
                        if (land != unitData.targetCommon || flying != unitData.targetFlying)
                        {
                            AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>();
                            if (trigger != null)
                            {
                                trigger.tags.Clear();
                                if (land == true)
                                {
                                    trigger.tags.Add("Enemy");
                                }
                                if (flying == true)
                                {
                                    trigger.tags.Add("FlyingEnemy");
                                }
                            }
                            unitData.targetCommon = land;
                            unitData.targetFlying = flying;
                        }
                    }
                }

                if (myState == MyState.Barracks)
                {
                    if (unitData.spawner != null)
                    {
                        // Defenders number
                        EditorGUILayout.LabelField("Defenders number");
                        unitData.spawner.maxNum = EditorGUILayout.IntSlider(unitData.spawner.maxNum, 1, 3);

                        // Cooldown between defenders spawning
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Cooldown");
                        unitData.spawner.cooldown = EditorGUILayout.FloatField(unitData.spawner.cooldown);
                        EditorGUILayout.EndHorizontal();
                    }

                    if (unitData.range != null)
                    {
                        // Range
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.PrefixLabel("Range");
                        unitData.range.transform.localScale = EditorGUILayout.FloatField(unitData.range.transform.localScale.x) * Vector3.one;
                        EditorGUILayout.EndHorizontal();
                    }

                    if (unitData.spawner != null)
                    {
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        GUILayout.Label("Defender");
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();

                        // Defender prefab
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button(contents.chooseDefenderButton, GUILayout.MaxWidth(60f), GUILayout.MaxHeight(60f)) == true)
                        {
                            ShowPicker <GameObject>(PickerState.Defenders, Lables.defender);
                        }
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();
                    }
                }

                if (myState == MyState.Tower || myState == MyState.Barracks)
                {
                    if (unitData.range != null)
                    {
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        GUILayout.Label("Range");
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();

                        // Show range
                        unitData.range.SetActive(EditorGUILayout.Toggle("Show range", unitData.range.activeSelf));
                    }

                    if (unitData.towerActions != null)
                    {
                        EditorGUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        GUILayout.Label("Actions");
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.EndHorizontal();

                        unitData.towerActions.gameObject.SetActive(EditorGUILayout.Toggle("Show actions", unitData.towerActions.gameObject.activeSelf));

                        // Actions buttons
                        if (unitData.towerActions.gameObject.activeSelf == true)
                        {
                            TowerAction action = (Selection.activeObject as GameObject).GetComponent <TowerAction>();

                            EditorGUILayout.BeginHorizontal();
                            if (GUILayout.Button(contents.add, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                            {
                                ShowPicker <GameObject>(PickerState.TowerActions, Lables.towerAction);
                            }
                            GUILayout.FlexibleSpace();
                            if (GUILayout.Button(contents.prev, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                            {
                                Selection.activeObject = unitData.towerActions.GetPrevioustAction(Selection.activeObject as GameObject);
                            }
                            if (GUILayout.Button(contents.next, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                            {
                                Selection.activeObject = unitData.towerActions.GetNextAction(Selection.activeObject as GameObject);
                            }
                            GUILayout.FlexibleSpace();
                            if (GUILayout.Button(contents.remove, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true)
                            {
                                if (action != null)
                                {
                                    DestroyImmediate(action.gameObject);
                                    Selection.activeObject = unitData.gameObject;
                                }
                            }
                            EditorGUILayout.EndHorizontal();

                            if (action != null)
                            {
                                EditorGUILayout.BeginHorizontal();
                                GUILayout.FlexibleSpace();
                                GUILayout.Label(action.name);
                                GUILayout.FlexibleSpace();
                                EditorGUILayout.EndHorizontal();


                                TowerActionsGUI(action);
                            }
                        }
                    }
                }

                // New object selected in picker window
                if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
                {
                    pickedObject = EditorGUIUtility.GetObjectPickerObject();
                    if (pickedObject != null)
                    {
                        switch (pickerState)
                        {
                        case PickerState.BulletAlly:
                        case PickerState.BulletEnemy:
                            if (unitData.attack != null && unitData.attack is AttackRanged)
                            {
                                (unitData.attack as AttackRanged).arrowPrefab = pickedObject as GameObject;
                                contents.chooseBulletButton.image             = AssetPreview.GetAssetPreview((unitData.attack as AttackRanged).arrowPrefab);
                            }
                            break;

                        case PickerState.Defenders:
                            if (unitData.spawner != null)
                            {
                                unitData.spawner.prefab             = pickedObject as GameObject;
                                contents.chooseDefenderButton.image = AssetPreview.GetAssetPreview(unitData.spawner.prefab);
                            }
                            break;

                        case PickerState.Towers:
                        {
                            TowerActionBuild towerActionBuild = (Selection.activeObject as GameObject).GetComponent <TowerActionBuild>();
                            if (towerActionBuild != null)
                            {
                                towerActionBuild.towerPrefab = pickedObject as GameObject;
                                EditorUtility.SetDirty(towerActionBuild.gameObject);
                            }
                        }
                        break;

                        case PickerState.Icons:
                        {
                            TowerAction towerAction = (Selection.activeObject as GameObject).GetComponent <TowerAction>();
                            if (towerAction != null)
                            {
                                Image image = towerAction.enabledIcon.GetComponent <Image>();
                                if (image != null)
                                {
                                    image.sprite = pickedObject as Sprite;
                                    EditorUtility.SetDirty(towerAction.gameObject);
                                }
                            }
                        }
                        break;
                        }
                    }
                }
                // Picker window closed
                if (Event.current.commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow)
                {
                    if (pickedObject != null)
                    {
                        switch (pickerState)
                        {
                        case PickerState.TowerActions:
                            if (unitData.towerActions != null)
                            {
                                unitData.towerActions.AddAction(pickedObject as GameObject);
                            }
                            break;

                        case PickerState.Features:
                            if (unitData.aiFeature != null)
                            {
                                unitData.aiFeature.AddFeature(pickedObject as GameObject);
                            }
                            break;
                        }
                    }
                    pickedObject = null;
                    pickerState  = PickerState.None;
                }
                break;
            }

            if (myState != MyState.Disabled)
            {
                GUILayout.Space(guiSpace);

                // Apply changes button
                if (unitData.gameObject != null && PrefabUtility.GetPrefabType(unitData.gameObject) != PrefabType.None)
                {
                    if (GUILayout.Button(contents.applyChangesButton) == true)
                    {
                        if (unitData.towerActions != null)
                        {
                            unitData.towerActions.gameObject.SetActive(false);
                        }
                        if (unitData.range != null)
                        {
                            unitData.range.SetActive(false);
                        }
                        PrefabUtility.ReplacePrefab(unitData.gameObject.gameObject, PrefabUtility.GetPrefabParent(unitData.gameObject.gameObject), ReplacePrefabOptions.ConnectToPrefab);
                    }

                    // Remove from scene button
                    if (GUILayout.Button(contents.removeFromSceneButton) == true)
                    {
                        DestroyImmediate(unitData.gameObject.gameObject);
                        Selection.activeObject = null;
                    }
                }
            }
        }
        else
        {
            EditorGUILayout.HelpBox("Editor disabled in play mode", MessageType.Info);
        }
    }