Select An Attack Target With Button

Hello!

I have an array of enemy objects and an Attack Button that executes Attack() on click. When I press my attack button, I would like another select button to appear above the first enemy in my enemy array and then when I press right or left it will go to the next enemy so that I can choose who to attack. I can’t seem to come up with a way to implement this. My brain is fried over this, so any help would be GREATLY appreciated! :slight_smile:

Here is an example of what I would like to accomplish:

This should at least get you started, although I don’t really know any of the implementation details for your project so it’s hard for me to tell if this will be of any use for you. In the future, you’ll probably get a lot better feedback if you provide some snippets of code of what you’ve tried first to give people a good idea of how we can help! :slight_smile:

/* pseudocode-ish */

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Assertions;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// This is the UI component that will hover around the selected enemy:
/// </summary>
public class EnemySelector: MonoBehaviour
{

    // Box collider associated with the cursor..
    // Could be replaced with explicit height if wanting to avoid using physics.
    public BoxCollider2D cursorCollider;

    /// <summary>
    /// Takes in the enemy class selected out of the array and a margin for padding
    /// More margin = more space above the enemies head.
    /// </summary>
    public void SetCursor(MyEnemyClass enemy, float margin = 1.0f)
    {
        // Get half the height of the enemy: (the radius)
        // If your enemy origin is at the bottom of the bounding box, ignore the 1/2 multiplication.
        float enemyHeightRadius = enemy.GetHeight() * 0.5f;

        // Get the position of the enemy:
        Vector2 enemyPosition = enemy.GetPosition();

        // Calculate where the pointer should go:
        float x = enemyPosition.x;

        // Get the point where the BOTTOM of the cursor should be:
    
        float y = enemyPosition.y + enemyHeightRadius + margin;
        // Add the radius of the cursor object:
        // This relies on the origin of the object being centered. If the origin is at the bottom, skip this.
        y += this.GetHeight() * 0.5f;

        // Set the position of the cursor:
        cursorObj.transform.position = new Vector3(x, y, 0.0f);

        // Done.

    }


    private float GetHeight()
    {
        // Get the scale-adjusted height of the cursor:
        return (cursorCollider.size.y * this.gameObject.transform.scale.y);
    }
}


/// <summary>
/// An example of the enemy class you'll have to fit to your implementation
/// </summary>
public class MyEnemyClass : MonoBehaviour
{

    // Some type of collider attached to the enemy.
    // This could also be a set value if you want to avoid involving physics..
    public BoxCollider2D enemyCollider;

    // Get the position of the enemy
    // In a 3D game, this could be replaced with Vector3
    public Vector2 GetPosition()
    {
        return this.gameObject.transform.position;
    }

    // Get the height of the enemy collider
    public float GetHeight()
    {
        // Get the scale-adjusted height of the enemy:
        return (enemyCollider.size.y * this.gameObject.transform.scale.y);
    }

}

/// <summary>
/// This is an example of how it might be used:
/// </summary>
public class EnemyPicker :MonoBehaviour
{

    // A Reference to the cursor:
    public EnemySelector cursor;

    // The list of enemies that are alive:
    public List<MyEnemyClass> enemiesInPlay;

    // Buttons for selecting:
        // They'll need something for turning them on and off
    public Button leftArrow;
    public Button rightArrow;


    // The current selection:
    private int selection;

    void Start()
    {
        // Make sure you've initialized correctly in the editor:
        Assert.IsNotNull(cursor);
        Assert.IsNotNull(leftArrow);
        Assert.IsNotNull(rightArrow);
       
        // If you don't want to set the OnClick events in the editor:
        leftArrow.onClick.AddListener(OnLeftArrowClick);
        rightArrow.onClick.AddListener(OnRightArrowClick);

        // Set default values:
        Wash();
    }

    // When your Attack() method is called, it should call this to start the selection.
    public void StartSelectingEnemies()
    {
        Wash();
        // Turn on the right and left buttons:
            // {...}

        // Finally, make sure to set the cursor originally. (and turn it on)
        this.UpdateSelection()
    }

    public void OnLeftArrowClick()
    {
        // Decrement the selection:
        selection--;
        // Wrap-around (if desired)
        if(selection < 0)
        {
            selection = enemiesInPlay.Count - 1;
        }

        this.UpdateSelection();
    }

    public void OnRightArrowClick()
    {
        // Increment selection:
        selection++;
        // Wrap-around:
        if(selection > enemiesInPlay.Count - 1)
        {
            selection = 0;
        }

        this.UpdateSelection();
    }


    // Helpers:
    private void UpdateSelection()
    {
        // Set the selection to the currently selected index:
        this.cursor.SetSelection(enemiesInPlay[selection]);
    }

    // Resets values to be nice and neat:
    private void Wash()
    {
        selection = 0;
    }
}